From 2d737f18f4d19a79d0b8d8403c659f4d965db4ca Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 19 Aug 2025 13:45:22 -0700 Subject: [PATCH 001/173] reset branch specifier to develop --- Gemfile | 10 +++++----- Gemfile.lock | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Gemfile b/Gemfile index 241f891d9..0289d404c 100644 --- a/Gemfile +++ b/Gemfile @@ -43,11 +43,11 @@ gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 gem 'redcarpet' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'master' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'develop' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 5a5df479d..c2ad88e7a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 26c0a69e67ac59778a46caf51202ebd38ccac767 - branch: master + revision: 87a21a76bc61392d0629a19c8a18593f606b52e5 + branch: develop specs: goo (0.0.2) addressable (~> 2.8) @@ -16,8 +16,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 4fb9114b80b99f0a654c7f70aaa96839c74fc615 - branch: master + revision: 55e8cbfac358b2c40deb0bd963bfe6dee91e8347 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -27,8 +27,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 8d67188e7f21014234359b71bb93a9d1256c320c - branch: master + revision: c4f16085b3e34b1e38e30232988297016e1f0e39 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -45,8 +45,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: c6a18eb7700b23a1a4f1e32ebc94003bf75efe93 - branch: master + revision: 76d9516adc3c5c6d5c95f21f307bdd60eb3e0acd + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -56,8 +56,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 2f22b1b19bd749c5625af798e2ad132f833309cb - branch: master + revision: 061f530204f5a08d26ad623e31cb2bbf398137bb + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -73,7 +73,7 @@ GIT rack rack-test rsolr - rubyzip + rubyzip (~> 3.0) GIT remote: https://github.com/ncbo/sparql-client.git @@ -271,7 +271,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0805) + mime-types-data (3.2025.0819) mini_mime (1.1.5) minitest (5.25.5) minitest-hooks (1.5.2) @@ -346,7 +346,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.25.1) + redis-client (0.25.2) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -381,7 +381,7 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.0.0) + rubyzip (3.0.1) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) signet (0.20.0) From 1c52fc0710bcd055e592bdc8f8413895cfa28282 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 29 Aug 2025 15:18:30 -0700 Subject: [PATCH 002/173] Gemfile.lock update --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c2ad88e7a..9e157f177 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 87a21a76bc61392d0629a19c8a18593f606b52e5 + revision: ca5f9d858eef89923903236fe6f76c78271e538d branch: develop specs: goo (0.0.2) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 061f530204f5a08d26ad623e31cb2bbf398137bb + revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 branch: develop specs: ontologies_linked_data (0.0.1) @@ -271,7 +271,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0819) + mime-types-data (3.2025.0826) mini_mime (1.1.5) minitest (5.25.5) minitest-hooks (1.5.2) @@ -286,7 +286,7 @@ GEM net-http (0.6.0) uri net-http-persistent (2.9.4) - net-imap (0.5.9) + net-imap (0.5.10) date net-protocol net-pop (0.1.2) @@ -381,7 +381,7 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.0.1) + rubyzip (3.0.2) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) signet (0.20.0) From 759dbc08eeae5f83b9a23bc14b3e1f8ac68c9512 Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 4 Sep 2025 14:13:14 -0700 Subject: [PATCH 003/173] implemented an endpoint for bulk submission deletions via process_long_operation --- Gemfile.lock | 24 ++--- controllers/admin_controller.rb | 31 ------- controllers/ontologies_controller.rb | 81 +++++++++++++++++ .../ontology_submissions_controller.rb | 73 +++++++++++++++ .../validate_ontology_file_controller.rb | 4 - helpers/application_helper.rb | 37 +++++++- .../test_ontology_submissions_controller.rb | 89 +++++++++++++++++++ 7 files changed, 291 insertions(+), 48 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c2ad88e7a..039ba2a59 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: c4f16085b3e34b1e38e30232988297016e1f0e39 + revision: 948458c4be06e28ceae0d900691afbf924ed5b3c branch: develop specs: ncbo_cron (0.0.1) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 061f530204f5a08d26ad623e31cb2bbf398137bb + revision: 4e58bcebfe54789959f072663a668fca1a1b2039 branch: develop specs: ontologies_linked_data (0.0.1) @@ -167,7 +167,7 @@ GEM ffi (1.17.2-x86_64-darwin) ffi (1.17.2-x86_64-linux-gnu) ffi (1.17.2-x86_64-linux-musl) - gapic-common (1.0.1) + gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) google-cloud-env (~> 2.2) @@ -213,31 +213,31 @@ GEM multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - grpc (1.74.0) + grpc (1.74.1) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-aarch64-linux-gnu) + grpc (1.74.1-aarch64-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-aarch64-linux-musl) + grpc (1.74.1-aarch64-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-arm64-darwin) + grpc (1.74.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86-linux-gnu) + grpc (1.74.1-x86-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86-linux-musl) + grpc (1.74.1-x86-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-darwin) + grpc (1.74.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-linux-gnu) + grpc (1.74.1-x86_64-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-linux-musl) + grpc (1.74.1-x86_64-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) haml (5.2.2) diff --git a/controllers/admin_controller.rb b/controllers/admin_controller.rb index 7ae6d8009..d6a23b90a 100644 --- a/controllers/admin_controller.rb +++ b/controllers/admin_controller.rb @@ -129,37 +129,6 @@ class AdminController < ApplicationController private - def process_long_operation(timeout, args) - process_id = "#{Time.now.to_i}_#{args[:name]}" - redis.setex process_id, timeout, MultiJson.dump("processing") - proc = Proc.new { - error = {} - begin - yield(args) - rescue Exception => e - msg = "Error #{args[:message]} - #{e.class}: #{e.message}" - puts "#{msg}\n#{e.backtrace.join("\n\t")}" - error[:errors] = [msg] - end - redis.setex process_id, timeout, MultiJson.dump(error.empty? ? "done" : error) - } - - fork = true # set to false for testing - if fork - pid = Process.fork do - proc.call - end - Process.detach(pid) - else - proc.call - end - process_id - end - - def redis - Redis.new(host: Annotator.settings.annotator_redis_host, port: Annotator.settings.annotator_redis_port, timeout: 30) - end - def redis_goo Redis.new(host: LinkedData.settings.goo_redis_host, port: LinkedData.settings.goo_redis_port, timeout: 30) end diff --git a/controllers/ontologies_controller.rb b/controllers/ontologies_controller.rb index a4c207232..a8abcb327 100644 --- a/controllers/ontologies_controller.rb +++ b/controllers/ontologies_controller.rb @@ -1,3 +1,5 @@ +require 'time' + class OntologiesController < ApplicationController namespace "/ontologies" do @@ -176,6 +178,85 @@ def create_ontology reply 201, ont end + + namespace "/:acronym/admin" do + + get '/log' do + ont = Ontology.find(params["acronym"]).first + entries = [] + + if ont + ont.bring(:viewingRestriction) + ont.bring(:administeredBy) + ont.bring(:acl) + check_access(ont) + latest_any = ont.latest_submission(status: :any) + + if latest_any + log_path = "#{LinkedData.settings.repository_folder}/#{NcboCron::Models::OntologiesReport.new.log_file(params["acronym"], latest_any.submissionId.to_s)}" + + if !log_path.empty? && File.file?(log_path) + file = File.open(log_path, "rb") + log_contents = file.read + file.close + + severity_param = params['severity']&.split(',')&.map { |s| s.strip.upcase } # ['DEBUG', 'ERROR'] + entries = parse_log(log_contents, severity_param) + end + end + end + + reply entries + end + + private + + def parse_log(log_text, allowed_severities = nil) + valid_severities = %w[ERROR DEBUG INFO] + + # Sanitize and validate allowed severities + allowed = Array(allowed_severities).map(&:upcase) & valid_severities + filter_enabled = !allowed.empty? + + entries = [] + + log_text.each_line do |line| + line.strip! + + # Match lines with timestamp + match = + line.match(/(?[A-Z]), \[(?[^\]]+)\] +(?\w+) -- : (?.+)/) || + # Match legacy format (no timestamp) + line.match(/(?\w+) -- : (?.+)/) + + next unless match + + entry = { + level: match[:level] || 'I', + timestamp: match.names.include?('timestamp') ? match[:timestamp].split('.').first : nil, + severity: match[:severity], + message: clean_message(match[:message]) + } + + entries << entry if !filter_enabled || allowed.include?(entry[:severity]) + end + + # Group by severity, sort within each group by timestamp DESC, then flatten in severity priority order + valid_severities.flat_map do |sev| + group = entries.select { |e| e[:severity] == sev } + group.sort_by { |e| e[:timestamp] ? Time.parse(e[:timestamp]) : Time.at(0) }.reverse + end + end + + def clean_message(raw) + raw + .gsub(/\A\[\[?"?/, '') # strip leading [[ or [" etc + .gsub(/"?\]?\]?\z/, '') # strip trailing ]] + .gsub('\\n', "\n") # replace \n (escaped) with real newline + .gsub('\\t', "\t") # replace \t (escaped) with real tab + .strip + end + end end namespace "/ontologies_full" do diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index be38f3161..3a6888e57 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -1,3 +1,5 @@ +require 'multi_json' + class OntologySubmissionsController < ApplicationController get "/submissions" do check_last_modified_collection(LinkedData::Models::OntologySubmission) @@ -90,6 +92,77 @@ class OntologySubmissionsController < ApplicationController halt 204 end + delete do + ont = Ontology.find(params["acronym"]).first + error 422, "You must provide an existing ontology `acronym` to delete its submissions" if ont.nil? + + raw = params["ontology_submission_ids"] + ids = + case raw + when Array + raw + when String + raw.split(",") + else + [] + end + + ids = ids.map { |v| v.to_s.strip }.reject(&:empty?).map(&:to_i).uniq + error 422, "`ontology_submission_ids` must be a non-empty array or comma-separated list" if ids.empty? + + args = { name: "bulk_delete_submissions_#{params['acronym']}", message: "deleting ontology submissions" } + process_id = process_long_operation(900, args) do |_args| + ont.bring(:submissions) + found = ont.submissions.select { |s| + s.bring(:submissionId) + ids.include?(s.submissionId.to_i) + } + found_ids = found.map { |s| s.submissionId.to_i } + missing = ids - found_ids + deleted_ids = [] + + if found.respond_to?(:each) + errors = [] + found.each do |s| + begin + s.delete + deleted_ids << s.submissionId.to_i + rescue => e + errors << { id: (s.respond_to?(:id) ? s.id : nil), error: "#{e.class}: #{e.message}" } + end + end + end + + payload = { deleted_ids: deleted_ids, deleted_count: deleted_ids.size, missing_ids: missing } + payload[:errors] = errors if defined?(errors) && errors.any? + payload + end + + reply 202, { process_id: process_id } + end + + # Polling endpoint for the bulk-delete long operation + # GET /ontologies/:acronym/submissions/bulk_delete/:process_id + get '/bulk_delete/:process_id' do + raw = redis.get(params["process_id"]) + stored = raw.nil? ? nil : MultiJson.load(raw) + error 404, "Process id #{params['process_id']} does not exist" if stored.nil? + + # If the job stored "done", report minimal success; if it stored a hash, return it. + if stored == "processing" + reply 200, { status: "processing" } + elsif stored == "done" + reply 200, { status: "done" } + elsif stored.is_a?(Hash) && stored["errors"] + reply 200, stored + else + # Assume it's the success payload produced in the worker + payload = stored.is_a?(Hash) ? stored : {} + payload["status"] = "done" unless payload["status"] + reply 200, payload + end + end + ## # Download a submission get '/:ontology_submission_id/download' do diff --git a/controllers/validate_ontology_file_controller.rb b/controllers/validate_ontology_file_controller.rb index 8e52f18e2..6562357de 100644 --- a/controllers/validate_ontology_file_controller.rb +++ b/controllers/validate_ontology_file_controller.rb @@ -52,10 +52,6 @@ class ValidateOntologyFileController < ApplicationController private - def redis - Redis.new(host: Annotator.settings.annotator_redis_host, port: Annotator.settings.annotator_redis_port) - end - ERROR_FORMAT_MAP = { "obo" => ["org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParser"], "owl" => [ diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index f69f1f8fd..497f0629c 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -1,4 +1,6 @@ require 'sinatra/base' +require 'sinatra/namespace' +require 'multi_json' require 'date' require 'rdf' require 'uri' @@ -450,6 +452,40 @@ def include_param_contains?(str) return class_params_include || params_include end + # Long-operation helper modeled after the original from AdminController#process_long_operation + def process_long_operation(timeout, args, &block) + process_id = "#{Time.now.to_i}_#{args[:name]}" + redis.setex process_id, timeout, MultiJson.dump("processing") + + worker = Proc.new do + result = {} + begin + result = block.call(args) || {} + rescue Exception => e + msg = "Error #{args[:message]} - #{e.class}: #{e.message}" + puts "#{msg}\n#{e.backtrace.join("\n\t")}" + result = { errors: [msg] } + end + # Store the result (either {errors: [...]} or a success payload) + redis.setex process_id, timeout, MultiJson.dump(result.empty? ? "done" : result) + end + + # Use a fork like AdminController; set to false for testing if needed + fork_process = true + if fork_process + pid = Process.fork { worker.call } + Process.detach(pid) + else + worker.call + end + + process_id + end + + def redis + Redis.new(host: Annotator.settings.annotator_redis_host, port: Annotator.settings.annotator_redis_port, timeout: 30) + end + private def naive_expiring_cache_write(key, object, timeout = 60) @@ -465,7 +501,6 @@ def naive_expiring_cache_read(key) return object[:object] end - def save_submission_language(submission, language_property = :naturalLanguage) request_lang = RequestStore.store[:requested_lang] diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index c8136d38f..5854217bd 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -139,6 +139,95 @@ def test_delete_ontology_submission get "/ontologies/#{acronym}/submissions/#{submission_to_delete}" assert_equal(404, last_response.status, msg=get_errors(last_response)) end + + + + + + + + + def test_delete_ontology_submissions + submission_count = 5 + # Create a single ontology with 10 submissions + num_onts_created, created_ont_acronyms = create_ontologies_and_submissions( + ont_count: 1, + random_submission_count: false, + submission_count: submission_count + ) + acronym = created_ont_acronyms.first + all_ids = (1..submission_count).to_a + delete_ids = all_ids.sample(3).sort + keep_ids = (all_ids - delete_ids).sort + assert_equal 2, keep_ids.size, "Expected 2 IDs to be kept" + + # Kick off the long-running bulk delete via the collection DELETE endpoint + payload = MultiJson.dump({ ontology_submission_ids: delete_ids }) + delete "/ontologies/#{acronym}/submissions", payload, "CONTENT_TYPE" => "application/json" + + assert_equal 202, last_response.status, msg=get_errors(last_response) + body = MultiJson.load(last_response.body) + assert body["process_id"], "Expected process_id in response for bulk delete" + + # Poll the bulk_delete status endpoint until it's done (or timeout) + process_id = body["process_id"] + max_attempts = 100 + attempts = 0 + status_payload = nil + + loop do + get "/ontologies/#{acronym}/submissions/bulk_delete/#{process_id}" + assert_equal 200, last_response.status, msg=get_errors(last_response) + status_payload = MultiJson.load(last_response.body) + + break if status_payload["status"] == "done" || (status_payload.is_a?(Hash) && (status_payload["deleted_ids"] || status_payload["errors"])) + attempts += 1 + assert attempts < max_attempts, "Timed out waiting for bulk delete to finish" + sleep 0.1 + end + + # Validate result payload when present + if status_payload["deleted_ids"] + # Only the chosen 8 should be deleted + assert_equal delete_ids, status_payload["deleted_ids"].map(&:to_i).sort, "Deleted IDs mismatch" + assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" + assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") + end + + # Deleted ones should be gone + delete_ids.each do |sid| + get "/ontologies/#{acronym}/submissions/#{sid}" + assert_equal 404, last_response.status, msg="Submission #{sid} should be gone, but GET returned #{last_response.status}" + end + + # Kept ones should still be present + keep_ids.each do |sid| + get "/ontologies/#{acronym}/submissions/#{sid}" + assert last_response.ok?, msg="Submission #{sid} should still exist, but GET returned #{last_response.status}" + end + end + + + + + + + + + + + + + + + + + + + + + + def test_download_submission num_onts_created, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: false) From 2e1ab476abb8eb8e5ea279eb3ab5f0c94a244a8c Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 4 Sep 2025 15:38:03 -0700 Subject: [PATCH 004/173] added security check to the bulk submission deletion endpoint --- Gemfile.lock | 22 +++++++++---------- .../ontology_submissions_controller.rb | 20 ++++++++--------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 039ba2a59..c7e836a92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 87a21a76bc61392d0629a19c8a18593f606b52e5 + revision: ca5f9d858eef89923903236fe6f76c78271e538d branch: develop specs: goo (0.0.2) @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 948458c4be06e28ceae0d900691afbf924ed5b3c + revision: 9113d0760515495e6f213daf041e2ba391178ae3 branch: develop specs: ncbo_cron (0.0.1) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 4e58bcebfe54789959f072663a668fca1a1b2039 + revision: e8980335667cfdf3687be0ce1adbeaa58c62e7c9 branch: develop specs: ontologies_linked_data (0.0.1) @@ -205,11 +205,11 @@ GEM grpc (~> 1.41) googleapis-common-protos-types (1.20.0) google-protobuf (>= 3.18, < 5.a) - googleauth (1.14.0) + googleauth (1.15.0) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.2) google-logging-utils (~> 0.1) - jwt (>= 1.4, < 3.0) + jwt (>= 1.4, < 4.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) @@ -253,7 +253,7 @@ GEM json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) - jwt (2.10.2) + jwt (3.1.2) base64 kgio (2.11.4) language_server-protocol (3.17.0.5) @@ -271,7 +271,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0819) + mime-types-data (3.2025.0902) mini_mime (1.1.5) minitest (5.25.5) minitest-hooks (1.5.2) @@ -286,7 +286,7 @@ GEM net-http (0.6.0) uri net-http-persistent (2.9.4) - net-imap (0.5.9) + net-imap (0.5.10) date net-protocol net-pop (0.1.2) @@ -381,13 +381,13 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.0.1) + rubyzip (3.0.2) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) - signet (0.20.0) + signet (0.21.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 3.0) + jwt (>= 1.5, < 4.0) multi_json (~> 1.10) simplecov (0.22.0) docile (~> 1.1) diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index 3a6888e57..6571aabed 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -95,7 +95,7 @@ class OntologySubmissionsController < ApplicationController delete do ont = Ontology.find(params["acronym"]).first error 422, "You must provide an existing ontology `acronym` to delete its submissions" if ont.nil? - + check_access(ont) raw = params["ontology_submission_ids"] ids = case raw @@ -120,16 +120,14 @@ class OntologySubmissionsController < ApplicationController found_ids = found.map { |s| s.submissionId.to_i } missing = ids - found_ids deleted_ids = [] - - if found.respond_to?(:each) - errors = [] - found.each do |s| - begin - s.delete - deleted_ids << s.submissionId.to_i - rescue => e - errors << { id: (s.respond_to?(:id) ? s.id : nil), error: "#{e.class}: #{e.message}" } - end + errors = [] + + found.each do |s| + begin + s.delete + deleted_ids << s.submissionId.to_i + rescue => e + errors << { id: (s.respond_to?(:id) ? s.id : nil), error: "#{e.class}: #{e.message}" } end end From 23c2ccd008610a305d8ce56fc10ba33ff11c45d3 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 16 Sep 2025 20:22:52 -0700 Subject: [PATCH 005/173] an improved input parsing for bulk submission deletion --- Gemfile.lock | 2 +- .../ontology_submissions_controller.rb | 42 ++++++++++++------- .../test_ontology_submissions_controller.rb | 30 ------------- 3 files changed, 27 insertions(+), 47 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c7e836a92..a9a078bc7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 9113d0760515495e6f213daf041e2ba391178ae3 + revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 branch: develop specs: ncbo_cron (0.0.1) diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index 6571aabed..39a7de1e9 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -93,28 +93,29 @@ class OntologySubmissionsController < ApplicationController end delete do - ont = Ontology.find(params["acronym"]).first + ont = Ontology.find(params["acronym"]).include(:acronym, :administeredBy, :acl, :viewingRestriction, submissions: :submissionId).first error 422, "You must provide an existing ontology `acronym` to delete its submissions" if ont.nil? check_access(ont) raw = params["ontology_submission_ids"] - ids = - case raw - when Array - raw - when String - raw.split(",") - else - [] - end - - ids = ids.map { |v| v.to_s.strip }.reject(&:empty?).map(&:to_i).uniq + list = case raw + when Array + raw + when String + s = raw.strip + # If it's a JSON-like array string (e.g., "[1,2,3]"), strip brackets + if s.start_with?("[") && s.end_with?("]") + s = s[1..-2] + end + s.split(",") + else + [] + end + # Coerce to integers, removing any stray non-digits (like leftover brackets/spaces) + ids = list.map { |v| v.to_s.gsub(/[^0-9]/, "").strip }.reject(&:empty?).map(&:to_i).uniq error 422, "`ontology_submission_ids` must be a non-empty array or comma-separated list" if ids.empty? - args = { name: "bulk_delete_submissions_#{params['acronym']}", message: "deleting ontology submissions" } process_id = process_long_operation(900, args) do |_args| - ont.bring(:submissions) found = ont.submissions.select { |s| - s.bring(:submissionId) ids.include?(s.submissionId.to_i) } found_ids = found.map { |s| s.submissionId.to_i } @@ -124,7 +125,16 @@ class OntologySubmissionsController < ApplicationController found.each do |s| begin - s.delete + + + + + # s.delete + puts "deleting: #{s.id.to_s}" + + + + deleted_ids << s.submissionId.to_i rescue => e errors << { id: (s.respond_to?(:id) ? s.id : nil), error: "#{e.class}: #{e.message}" } diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 5854217bd..58f36a197 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -128,7 +128,6 @@ def test_patch_submission_ignores_system_controlled_attributes refute_includes updated_submission, "missingImports" end - def test_delete_ontology_submission num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1, random_submission_count: false, submission_count: 5) acronym = created_ont_acronyms.first @@ -140,13 +139,6 @@ def test_delete_ontology_submission assert_equal(404, last_response.status, msg=get_errors(last_response)) end - - - - - - - def test_delete_ontology_submissions submission_count = 5 # Create a single ontology with 10 submissions @@ -207,28 +199,6 @@ def test_delete_ontology_submissions end end - - - - - - - - - - - - - - - - - - - - - - def test_download_submission num_onts_created, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: false) assert_equal(1, num_onts_created, msg="Failed to create 1 ontology?") From b94c0e3134e120eafa907a2d21f74c25f38fe7c8 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 16 Sep 2025 20:41:07 -0700 Subject: [PATCH 006/173] updated the process_long_operation method to handle more cases --- helpers/application_helper.rb | 52 ++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index 497f0629c..f5d9ec782 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -1,6 +1,7 @@ require 'sinatra/base' require 'sinatra/namespace' require 'multi_json' +require 'securerandom' require 'date' require 'rdf' require 'uri' @@ -453,26 +454,45 @@ def include_param_contains?(str) end # Long-operation helper modeled after the original from AdminController#process_long_operation - def process_long_operation(timeout, args, &block) - process_id = "#{Time.now.to_i}_#{args[:name]}" - redis.setex process_id, timeout, MultiJson.dump("processing") - - worker = Proc.new do - result = {} + # Start: "processing" + # Success (empty/nil): "done" + # Success (payload): payload as-is (no status Hash) + # Error: { errors: ["..."] } + def process_long_operation(timeout, args = {}, &block) + name = (args[:name] || "job").to_s.gsub(/\s+/, "_") + message = (args[:message] || name).to_s + process_id = "#{Time.now.to_i}-#{name}-#{SecureRandom.hex(4)}" + + # 1) Immediately mark processing + redis.setex(process_id, timeout, MultiJson.dump("processing")) + + worker = proc do begin - result = block.call(args) || {} - rescue Exception => e - msg = "Error #{args[:message]} - #{e.class}: #{e.message}" - puts "#{msg}\n#{e.backtrace.join("\n\t")}" - result = { errors: [msg] } + result = block.call(args) + + # 2) Success. Preserve legacy string based responses + if result.nil? || (result.respond_to?(:empty?) && result.empty?) + redis.setex(process_id, timeout, MultiJson.dump("done")) + elsif result.is_a?(Hash) || result.is_a?(Array) || result.is_a?(String) || result.is_a?(Numeric) || result == true || result == false + redis.setex(process_id, timeout, MultiJson.dump(result)) + else + redis.setex(process_id, timeout, MultiJson.dump("done")) + end + rescue => e + # 3) Error → log + legacy error payload (no backtrace to clients) + msg = "Error #{message} - #{e.class}: #{e.message}" + log_msg = "#{msg}\n#{e.backtrace.join("\n\t")}" + if respond_to?(:logger) && logger + logger.error(log_msg) + else + $stderr.puts(log_msg) + end + redis.setex(process_id, timeout, MultiJson.dump(errors: [msg])) end - # Store the result (either {errors: [...]} or a success payload) - redis.setex process_id, timeout, MultiJson.dump(result.empty? ? "done" : result) end - # Use a fork like AdminController; set to false for testing if needed - fork_process = true - if fork_process + # 4) Background work (toggle via fork: false in tests) + if args.fetch(:fork, true) pid = Process.fork { worker.call } Process.detach(pid) else From 4727d98411bd28c1400b40b2422859c12ebdbc63 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 17 Sep 2025 15:43:14 -0700 Subject: [PATCH 007/173] updated sparql-client gem to point to master --- Gemfile | 3 ++- Gemfile.lock | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 0289d404c..0b080d3f9 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,8 @@ gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' -gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' +# gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'master' group :development do # bcrypt_pbkdf and ed35519 is required for capistrano deployments when using ed25519 keys; see https://github.com/miloserdow/capistrano-deploy/issues/42 diff --git a/Gemfile.lock b/Gemfile.lock index a9a078bc7..87d8b8f26 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,7 +78,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 512edc320b43e83971835dc046b4923485e8f70e - tag: v6.3.0 + branch: master specs: sparql-client (1.0.1) json_pure (>= 1.4) From 05ebc9b9e454c79b2884d5a43db5c1afc60a294d Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 23 Sep 2025 13:42:49 -0700 Subject: [PATCH 008/173] Gemfile.lock update --- Gemfile | 3 +-- Gemfile.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index 0b080d3f9..0289d404c 100644 --- a/Gemfile +++ b/Gemfile @@ -48,8 +48,7 @@ gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' -# gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'master' +gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' group :development do # bcrypt_pbkdf and ed35519 is required for capistrano deployments when using ed25519 keys; see https://github.com/miloserdow/capistrano-deploy/issues/42 diff --git a/Gemfile.lock b/Gemfile.lock index 87d8b8f26..09628ab47 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: ca5f9d858eef89923903236fe6f76c78271e538d + revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c branch: develop specs: goo (0.0.2) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: e8980335667cfdf3687be0ce1adbeaa58c62e7c9 + revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 branch: develop specs: ontologies_linked_data (0.0.1) @@ -78,7 +78,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 512edc320b43e83971835dc046b4923485e8f70e - branch: master + tag: v6.3.0 specs: sparql-client (1.0.1) json_pure (>= 1.4) @@ -120,7 +120,7 @@ GEM bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) - bigdecimal (3.2.2) + bigdecimal (3.2.3) builder (3.3.0) byebug (12.0.0) capistrano (3.19.2) @@ -137,7 +137,7 @@ GEM sshkit (~> 1.3) coderay (1.1.3) concurrent-ruby (1.3.5) - connection_pool (2.5.3) + connection_pool (2.5.4) crack (0.4.5) rexml cube-ruby (0.0.3) @@ -249,7 +249,7 @@ GEM domain_name (~> 0.5) i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.13.2) + json (2.15.0) json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) @@ -271,7 +271,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0902) + mime-types-data (3.2025.0916) mini_mime (1.1.5) minitest (5.25.5) minitest-hooks (1.5.2) @@ -346,7 +346,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.25.2) + redis-client (0.26.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -381,7 +381,7 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.0.2) + rubyzip (3.1.0) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) signet (0.21.0) From 935dfddd2ac1f23cbf30284445f05e8ecd71635f Mon Sep 17 00:00:00 2001 From: mdorf Date: Fri, 24 Oct 2025 16:37:01 -0700 Subject: [PATCH 009/173] fixes for submissions bulk delete method --- Gemfile.lock | 4 +-- .../ontology_submissions_controller.rb | 28 +++++++++++-------- helpers/slices_helper.rb | 12 ++++---- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 87d8b8f26..b25c74fc5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: ca5f9d858eef89923903236fe6f76c78271e538d + revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c branch: develop specs: goo (0.0.2) @@ -271,7 +271,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0902) + mime-types-data (3.2025.0916) mini_mime (1.1.5) minitest (5.25.5) minitest-hooks (1.5.2) diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index 39a7de1e9..afe0e15cd 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -113,11 +113,18 @@ class OntologySubmissionsController < ApplicationController # Coerce to integers, removing any stray non-digits (like leftover brackets/spaces) ids = list.map { |v| v.to_s.gsub(/[^0-9]/, "").strip }.reject(&:empty?).map(&:to_i).uniq error 422, "`ontology_submission_ids` must be a non-empty array or comma-separated list" if ids.empty? + args = { name: "bulk_delete_submissions_#{params['acronym']}", message: "deleting ontology submissions" } process_id = process_long_operation(900, args) do |_args| + latest_submission_id = ont.highest_submission_id(status: :ready) + max_submission_id = nil + found = ont.submissions.select { |s| - ids.include?(s.submissionId.to_i) + sid = s.submissionId.to_i + max_submission_id = sid if !latest_submission_id && (max_submission_id.nil? || sid > max_submission_id) + ids.include?(sid) } + latest_submission_id ||= max_submission_id found_ids = found.map { |s| s.submissionId.to_i } missing = ids - found_ids deleted_ids = [] @@ -125,22 +132,21 @@ class OntologySubmissionsController < ApplicationController found.each do |s| begin - - - - - # s.delete - puts "deleting: #{s.id.to_s}" - - - - + s.delete deleted_ids << s.submissionId.to_i rescue => e errors << { id: (s.respond_to?(:id) ? s.id : nil), error: "#{e.class}: #{e.message}" } end end + # If the latest READY submission is deleted, re-process the previous one, if exists + if latest_submission_id && deleted_ids.include?(latest_submission_id) + # Re-fetch ontology to avoid stale submissions cache + ont_refreshed = Ontology.find(params["acronym"]).include(submissions: :submissionId).first + new_latest_sub = ont_refreshed.latest_submission(status: :any) + NcboCron::Models::OntologySubmissionParser.new.queue_submission(new_latest_sub, all: true) if new_latest_sub + end + payload = { deleted_ids: deleted_ids, deleted_count: deleted_ids.size, missing_ids: missing } payload[:errors] = errors if defined?(errors) && errors.any? payload diff --git a/helpers/slices_helper.rb b/helpers/slices_helper.rb index 6f527f29d..d862073fe 100644 --- a/helpers/slices_helper.rb +++ b/helpers/slices_helper.rb @@ -4,16 +4,18 @@ module Sinatra module Helpers module SlicesHelper + def filter_for_slice(obj) return obj unless LinkedData.settings.enable_slices + return obj unless request.get? # only slice GET requests return obj unless slice_request? + return obj unless obj.is_a?(Enumerable) - slice = current_slice() + first = obj.first + return obj unless first && first.is_a?(LinkedData::Models::Ontology) - if obj.is_a?(Enumerable) && obj.first.is_a?(LinkedData::Models::Ontology) - obj = obj.select { |o| slice.ontology_id_set.include?(o.id.to_s) } - end - obj + slice = current_slice + obj.select { |o| slice.ontology_id_set.include?(o.id.to_s) } end def slice_request? From 3fc97b199ebb424016f4b302d72bc457c6fce985 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 27 Oct 2025 18:43:10 -0700 Subject: [PATCH 010/173] Gemfile.lock update --- Gemfile.lock | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4182f69e9..979b2b944 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 26c0a69e67ac59778a46caf51202ebd38ccac767 + revision: 5cac44e06a6bf0c093563dad66240ab07fec4d9c branch: master specs: goo (0.0.2) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 5a4f4d39aeb3ec567038b88ea962b796b2715915 + revision: 1a6d42628cfcf1704b96de45e27e81392333e343 branch: master specs: ontologies_linked_data (0.0.1) @@ -120,7 +120,7 @@ GEM bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) - bigdecimal (3.2.2) + bigdecimal (3.3.1) builder (3.3.0) byebug (12.0.0) capistrano (3.19.2) @@ -137,7 +137,7 @@ GEM sshkit (~> 1.3) coderay (1.1.3) concurrent-ruby (1.3.5) - connection_pool (2.5.3) + connection_pool (2.5.4) crack (0.4.5) rexml cube-ruby (0.0.3) @@ -146,7 +146,7 @@ GEM docile (1.4.1) domain_name (0.6.20240107) ed25519 (1.4.0) - faraday (2.13.4) + faraday (2.14.0) faraday-net_http (>= 2.0, < 3.5) json logger @@ -245,11 +245,11 @@ GEM tilt hashdiff (1.2.0) http-accept (1.7.0) - http-cookie (1.0.8) + http-cookie (1.1.0) domain_name (~> 0.5) i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.13.2) + json (2.15.2) json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) @@ -262,7 +262,8 @@ GEM logger (1.7.0) macaddr (1.7.2) systemu (~> 2.6.5) - mail (2.8.1) + mail (2.9.0) + logger mini_mime (>= 0.1.1) net-imap net-pop @@ -271,9 +272,9 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0819) + mime-types-data (3.2025.0924) mini_mime (1.1.5) - minitest (5.25.5) + minitest (5.26.0) minitest-hooks (1.5.2) minitest (> 5.3) minitest-stub_any_instance (1.0.3) @@ -286,7 +287,7 @@ GEM net-http (0.6.0) uri net-http-persistent (2.9.4) - net-imap (0.5.9) + net-imap (0.5.12) date net-protocol net-pop (0.1.2) @@ -346,7 +347,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.25.2) + redis-client (0.26.1) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -381,7 +382,7 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.0.1) + rubyzip (3.2.1) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) signet (0.20.0) @@ -436,7 +437,7 @@ GEM unicorn-worker-killer (0.4.5) get_process_mem (~> 0) unicorn (>= 4, < 7) - uri (1.0.3) + uri (1.0.4) uuid (2.3.9) macaddr (~> 1.0) webmock (3.19.1) From bdca27459885ca2bc347ddba8c387067e46b1234 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 31 Oct 2025 14:33:08 -0700 Subject: [PATCH 011/173] Refactor: use idiomatic Minitest assertions in ontology submissions tests Replace non-idiomatic assertions with Minitest equivalents: - assert(x == y) -> assert_equal - .eql?() -> assert_equal - assert !x.empty? -> assert_operator x.length, :>, 0 - submissions.all? -> submissions.each for better error messages Extract repeated contact validation into helper method to reduce duplication. Fix intermittent test failures by sorting array keys before comparison to handle non-deterministic ordering. refs ncbo/ontologies_api#197 --- .../test_ontology_submissions_controller.rb | 65 ++++++++++++------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 58f36a197..87a1b2c84 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -55,7 +55,7 @@ def test_submissions_for_given_ontology submissions_goo = OntologySubmission.where(ontology: { acronym: ontology}).to_a submissions = MultiJson.load(last_response.body) - assert submissions.length == submissions_goo.length + assert_equal submissions.length, submissions_goo.length end def test_create_new_submission_missing_file_and_pull_location @@ -70,7 +70,7 @@ def test_create_new_submission_file sub = MultiJson.load(last_response.body) get "/ontologies/#{@@acronym}" ont = MultiJson.load(last_response.body) - assert ont["acronym"].eql?(@@acronym) + assert_equal @@acronym, ont["acronym"] # Cleanup delete "/ontologies/#{@@acronym}/submissions/#{sub['submissionId']}" assert_equal(204, last_response.status, msg=get_errors(last_response)) @@ -88,21 +88,21 @@ def test_create_new_ontology_submission def test_patch_ontology_submission num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) ont = Ontology.find(created_ont_acronyms.first).include(submissions: [:submissionId, ontology: :acronym]).first - assert(ont.submissions.length > 0) + assert_operator ont.submissions.length, :>, 0 submission = ont.submissions[0] new_values = {description: "Testing new description changes"} patch "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}", MultiJson.dump(new_values), "CONTENT_TYPE" => "application/json" assert_equal(204, last_response.status, msg=get_errors(last_response)) get "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}" submission = MultiJson.load(last_response.body) - assert submission["description"].eql?("Testing new description changes") + assert_equal "Testing new description changes", submission["description"] end def test_patch_submission_ignores_system_controlled_attributes _, acronyms = create_ontologies_and_submissions(ont_count: 1) acronym = acronyms.first ontology = Ontology.find(acronym).include(submissions: [:submissionId, ontology: :acronym]).first - assert !ontology.submissions.empty? + assert_operator ontology.submissions.length, :>, 0 submission = ontology.submissions.first patch_payload = { @@ -303,14 +303,18 @@ def test_submissions_default_includes submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size - assert(submissions.all? { |sub| submission_default_attributes.eql?(submission_keys(sub)) }) + submissions.each do |sub| + assert_equal(submission_default_attributes, submission_keys(sub)) + end get("/ontologies/#{created_ont_acronyms.first}/submissions?display_links=false&display_context=false") assert last_response.ok? submissions = MultiJson.load(last_response.body) assert_equal 1, submissions.size - assert(submissions.all? { |sub| submission_default_attributes.eql?(submission_keys(sub)) }) + submissions.each do |sub| + assert_equal(submission_default_attributes, submission_keys(sub)) + end end def test_submissions_all_includes @@ -328,8 +332,10 @@ def submission_all_attributes submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size - assert(submissions.all? { |sub| submission_all_attributes.sort.eql?(submission_keys(sub).sort) }) - assert(submissions.all? { |sub| sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id])) }) + submissions.each do |sub| + assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) + assert_submission_contact_structure(sub) + end get("/ontologies/#{created_ont_acronyms.first}/submissions?include=all&display_links=false&display_context=false") @@ -337,22 +343,24 @@ def submission_all_attributes submissions = MultiJson.load(last_response.body) assert_equal 1, submissions.size - assert(submissions.all? { |sub| submission_all_attributes.sort.eql?(submission_keys(sub).sort) }) - assert(submissions.all? { |sub| sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id])) }) + submissions.each do |sub| + assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) + assert_submission_contact_structure(sub) + end get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=all&display_links=false&display_context=false") assert last_response.ok? sub = MultiJson.load(last_response.body) - assert(submission_all_attributes.sort.eql?(submission_keys(sub).sort)) - assert(sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id]))) + assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) + assert_submission_contact_structure(sub) get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=all&display_links=false&display_context=false") assert last_response.ok? sub = MultiJson.load(last_response.body) - assert(submission_all_attributes.sort.eql?(submission_keys(sub).sort)) - assert(sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id]))) + assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) + assert_submission_contact_structure(sub) end def test_submissions_custom_includes @@ -365,28 +373,32 @@ def test_submissions_custom_includes assert last_response.ok? submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size - assert(submissions.all? { |sub| include.split(',').eql?(submission_keys(sub)) }) - assert(submissions.all? { |sub| sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id])) }) + submissions.each do |sub| + assert_equal(include.split(','), submission_keys(sub)) + assert_submission_contact_structure(sub) + end get("/ontologies/#{created_ont_acronyms.first}/submissions?include=#{include}&display_links=false&display_context=false") assert last_response.ok? submissions = MultiJson.load(last_response.body) assert_equal 1, submissions.size - assert(submissions.all? { |sub| include.split(',').eql?(submission_keys(sub)) }) - assert(submissions.all? { |sub| sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id])) }) + submissions.each do |sub| + assert_equal(include.split(','), submission_keys(sub)) + assert_submission_contact_structure(sub) + end get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=#{include}&display_links=false&display_context=false") assert last_response.ok? sub = MultiJson.load(last_response.body) - assert(include.split(',').eql?(submission_keys(sub))) - assert(sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id]))) + assert_equal(include.split(','), submission_keys(sub)) + assert_submission_contact_structure(sub) get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=#{include}&display_links=false&display_context=false") assert last_response.ok? sub = MultiJson.load(last_response.body) - assert(include.split(',').eql?(submission_keys(sub))) - assert(sub["contact"] && (sub["contact"].first.nil? || sub["contact"].first.keys.eql?(%w[name email id]))) + assert_equal(include.split(','), submission_keys(sub)) + assert_submission_contact_structure(sub) end private @@ -394,4 +406,11 @@ def submission_keys(sub) sub.to_hash.keys - %w[@id @type id] end + def assert_submission_contact_structure(sub) + assert sub["contact"], "Contact should be present" + if sub["contact"].first + assert_equal(%w[name email id].sort, sub["contact"].first.keys.sort) + end + end + end From becf5d4ac2d2ccc078372d2894b08f1b12d7436d Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 31 Oct 2025 15:41:49 -0700 Subject: [PATCH 012/173] Refactor test_access_control_helper to use class instance variables - Replace class variables (@@) with class instance variables using accessors - Add attr_accessor definitions for shared test state - Modernize assertions to Minitest style (assert_equal, assert_includes, assert_nil) - Improve code formatting and readability --- test/helpers/test_access_control_helper.rb | 121 ++++++++++++--------- 1 file changed, 72 insertions(+), 49 deletions(-) diff --git a/test/helpers/test_access_control_helper.rb b/test/helpers/test_access_control_helper.rb index 19b0ae0fc..b008f9fcd 100644 --- a/test/helpers/test_access_control_helper.rb +++ b/test/helpers/test_access_control_helper.rb @@ -1,12 +1,18 @@ require_relative '../test_case_helpers' class TestAccessControlHelper < TestCaseHelpers + # Class instance vars with readers/writers + class << self + attr_accessor :usernames, :admin, :user1, :user2, :user3, :user, + :restricted_ont, :ont, :ont_patch, :restricted_user, + :old_security_setting + end def before_suite self.backend_4s_delete - @@usernames = ["user1", "user2", "user3", "admin"] - @@usernames.each do |username| + self.class.usernames = %w[user1 user2 user3 admin] + self.class.usernames.each do |username| user = LinkedData::Models::User.new( username: username, email: "#{username}@example.org", @@ -14,105 +20,122 @@ def before_suite ) user.save user.bring_remaining - self.class.class_variable_set(:"@@#{username}", user) + # create @user1, @user2, @user3, @admin on the class object + self.class.send(:"#{username}=", user) end - @@admin.role = [LinkedData::Models::Users::Role.find(LinkedData::Models::Users::Role::ADMIN).first] - @@admin.save + self.class.admin.role = [ + LinkedData::Models::Users::Role.find(LinkedData::Models::Users::Role::ADMIN).first + ] + self.class.admin.save onts = LinkedData::SampleData::Ontology.create_ontologies_and_submissions[2] - @@restricted_ont = onts.shift - @@restricted_ont.bring_remaining - @@restricted_ont.viewingRestriction = "private" - @@restricted_ont.acl = [@@user2, @@user3] - @@restricted_ont.administeredBy = [@@user1] - @@restricted_ont.save - @@restricted_user = @@restricted_ont.administeredBy.first - @@restricted_user.bring_remaining + self.class.restricted_ont = onts.shift + self.class.restricted_ont.bring_remaining + self.class.restricted_ont.viewingRestriction = "private" + self.class.restricted_ont.acl = [self.class.user2, self.class.user3] + self.class.restricted_ont.administeredBy = [self.class.user1] + self.class.restricted_ont.save + self.class.restricted_user = self.class.restricted_ont.administeredBy.first + self.class.restricted_user.bring_remaining - @@ont = onts.shift - @@ont.bring_remaining - @@user = @@ont.administeredBy.first - @@user.bring_remaining - @@old_security_setting = LinkedData.settings.enable_security + self.class.ont = onts.shift + self.class.ont.bring_remaining + self.class.user = self.class.ont.administeredBy.first + self.class.user.bring_remaining - @@ont_patch = onts.shift.bring_remaining + self.class.old_security_setting = LinkedData.settings.enable_security + self.class.ont_patch = onts.shift.bring_remaining LinkedData.settings.enable_security = true end def after_suite self.backend_4s_delete - LinkedData.settings.enable_security = @@old_security_setting unless @@old_security_setting.nil? + LinkedData.settings.enable_security = self.class.old_security_setting unless self.class.old_security_setting.nil? end def test_filtered_list - get "/ontologies", apikey: @@user.apikey + get "/ontologies", apikey: self.class.user.apikey onts = MultiJson.load(last_response.body) assert last_response.ok? - assert onts.length == 4 - assert onts.any? {|o| o["@id"] == @@ont.id.to_s} - refute onts.any? {|o| o["@id"] == @@restricted_ont.id.to_s} + assert_equal 4, onts.length + + ids = onts.map { |o| o["@id"] } + assert_includes ids, self.class.ont.id.to_s + refute_includes ids, self.class.restricted_ont.id.to_s end def test_direct_access - get "/ontologies/#{@@restricted_ont.acronym}", apikey: @@user.apikey - assert last_response.status == 403 + get "/ontologies/#{self.class.restricted_ont.acronym}", apikey: self.class.user.apikey + assert_equal 403, last_response.status end def test_allow_post_writes begin acronym = "SECURE_ONT" - params = {apikey: @@user2.apikey, acronym: acronym, name: "New test name", administeredBy: [@@user2.id.to_s]} + params = { + apikey: self.class.user2.apikey, + acronym: acronym, + name: "New test name", + administeredBy: [self.class.user2.id.to_s] + } post "/ontologies", MultiJson.dump(params), "CONTENT_TYPE" => "application/json" - assert last_response.status == 201 + assert_equal 201, last_response.status ensure ont = LinkedData::Models::Ontology.find(acronym).first - ont.delete(user: @@user2) if ont + ont.delete(user: self.class.user2) if ont ont = LinkedData::Models::Ontology.find(acronym).first - assert ont.nil? + assert_nil ont end end def test_delete_access begin acronym = "SECURE_ONT_DEL" # must be <= 16 chars - params = {apikey: @@user2.apikey, acronym: acronym, name: "New test name", administeredBy: [@@user2.id.to_s]} + params = { + apikey: self.class.user2.apikey, + acronym: acronym, + name: "New test name", + administeredBy: [self.class.user2.id.to_s] + } post "/ontologies", MultiJson.dump(params), "CONTENT_TYPE" => "application/json" - assert last_response.status == 201 - delete "/ontologies/#{acronym}?apikey=#{@@user.apikey}" - assert last_response.status == 403 - delete "/ontologies/#{acronym}?apikey=#{@@user2.apikey}" - assert last_response.status == 204 + assert_equal 201, last_response.status + + delete "/ontologies/#{acronym}?apikey=#{self.class.user.apikey}" + assert_equal 403, last_response.status + + delete "/ontologies/#{acronym}?apikey=#{self.class.user2.apikey}" + assert_equal 204, last_response.status ensure ont = LinkedData::Models::Ontology.find(acronym).first - ont.delete(user: @@user2) if ont + ont.delete(user: self.class.user2) if ont ont = LinkedData::Models::Ontology.find(acronym).first - assert ont.nil? + assert_nil ont end end def test_save_security_load_attributes - # We should make sure that attributes that are needed for security checks don't get overridden - params = {apikey: @@user.apikey, administeredBy: [@@user2.id.to_s]} - ont_url = "/ontologies/#{@@ont_patch.acronym}" + # Ensure security-critical attrs aren’t overridden + params = { apikey: self.class.user.apikey, administeredBy: [self.class.user2.id.to_s] } + ont_url = "/ontologies/#{self.class.ont_patch.acronym}" patch ont_url, MultiJson.dump(params), "CONTENT_TYPE" => "application/json" - assert last_response.status == 204 - get ont_url, apikey: @@user2.apikey + assert_equal 204, last_response.status + get ont_url, apikey: self.class.user2.apikey assert last_response.ok? ont = MultiJson.load(last_response.body) - assert ont["administeredBy"].include?(@@user2.id.to_s) + assert_includes ont["administeredBy"], self.class.user2.id.to_s end def test_write_access_denied - params = {apikey: @@user2.apikey, name: "New test name"} - patch "/ontologies/#{@@restricted_ont.acronym}", MultiJson.dump(params), "CONTENT_TYPE" => "application/json" - assert last_response.status == 403 + params = { apikey: self.class.user2.apikey, name: "New test name" } + patch "/ontologies/#{self.class.restricted_ont.acronym}", MultiJson.dump(params), "CONTENT_TYPE" => "application/json" + assert_equal 403, last_response.status end def test_based_on_access - get "/ontologies/#{@@restricted_ont.acronym}/submissions", apikey: @@user.apikey - assert last_response.status == 403 + get "/ontologies/#{self.class.restricted_ont.acronym}/submissions", apikey: self.class.user.apikey + assert_equal 403, last_response.status end end From daef301d506d38a0328adf307c64b2805e421a57 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 4 Nov 2025 12:42:48 -0800 Subject: [PATCH 013/173] test: clean up delete ontology submissions test logic and polling condition - Replace random .sample(3) with deterministic .first(3) - Use dynamic assertion for keep_ids count instead of hardcoded value - Capture process_id before use for clarity - Simplify polling loop condition to check only for 'done' or 'errors' - Clean up assertion message formatting for consistency --- .../test_ontology_submissions_controller.rb | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 87a1b2c84..1d372ae7d 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -141,7 +141,7 @@ def test_delete_ontology_submission def test_delete_ontology_submissions submission_count = 5 - # Create a single ontology with 10 submissions + # Create a single ontology with 5 submissions num_onts_created, created_ont_acronyms = create_ontologies_and_submissions( ont_count: 1, random_submission_count: false, @@ -149,9 +149,9 @@ def test_delete_ontology_submissions ) acronym = created_ont_acronyms.first all_ids = (1..submission_count).to_a - delete_ids = all_ids.sample(3).sort + delete_ids = all_ids.first(3) keep_ids = (all_ids - delete_ids).sort - assert_equal 2, keep_ids.size, "Expected 2 IDs to be kept" + assert_equal submission_count - delete_ids.size, keep_ids.size, "Unexpected keep_ids size" # Kick off the long-running bulk delete via the collection DELETE endpoint payload = MultiJson.dump({ ontology_submission_ids: delete_ids }) @@ -159,10 +159,10 @@ def test_delete_ontology_submissions assert_equal 202, last_response.status, msg=get_errors(last_response) body = MultiJson.load(last_response.body) - assert body["process_id"], "Expected process_id in response for bulk delete" + process_id = body["process_id"] + assert process_id, "Expected process_id in response for bulk delete" # Poll the bulk_delete status endpoint until it's done (or timeout) - process_id = body["process_id"] max_attempts = 100 attempts = 0 status_payload = nil @@ -172,7 +172,10 @@ def test_delete_ontology_submissions assert_equal 200, last_response.status, msg=get_errors(last_response) status_payload = MultiJson.load(last_response.body) - break if status_payload["status"] == "done" || (status_payload.is_a?(Hash) && (status_payload["deleted_ids"] || status_payload["errors"])) + status = status_payload.is_a?(Hash) ? status_payload["status"] : nil + has_errors = status_payload.is_a?(Hash) && status_payload["errors"] + break if status == "done" || has_errors + attempts += 1 assert attempts < max_attempts, "Timed out waiting for bulk delete to finish" sleep 0.1 @@ -180,7 +183,7 @@ def test_delete_ontology_submissions # Validate result payload when present if status_payload["deleted_ids"] - # Only the chosen 8 should be deleted + # Only the chosen 5 should be deleted assert_equal delete_ids, status_payload["deleted_ids"].map(&:to_i).sort, "Deleted IDs mismatch" assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") @@ -189,13 +192,13 @@ def test_delete_ontology_submissions # Deleted ones should be gone delete_ids.each do |sid| get "/ontologies/#{acronym}/submissions/#{sid}" - assert_equal 404, last_response.status, msg="Submission #{sid} should be gone, but GET returned #{last_response.status}" + assert_equal 404, last_response.status, "Submission #{sid} should be gone, but GET returned #{last_response.status} for #{sid}" end # Kept ones should still be present keep_ids.each do |sid| get "/ontologies/#{acronym}/submissions/#{sid}" - assert last_response.ok?, msg="Submission #{sid} should still exist, but GET returned #{last_response.status}" + assert last_response.ok?, "Submission #{sid} should still exist, but GET returned #{last_response.status}" end end From 51fbbb02b835c2b149b47955cb0c55df1069fbc8 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 4 Nov 2025 12:46:39 -0800 Subject: [PATCH 014/173] test: fix incorrect assertions and add verification for slice creation/deletion - Replace `assert 201, ...` with `assert_equal 201, ...` to properly compare response status. - Add GET checks after slice creation to confirm the new slice exists. - Remove redundant manual reset of LinkedData.settings.enable_security. - Update DELETE test to expect 204 (No Content) instead of 201. - Add GET checks after deletion to verify the slice was actually removed. --- test/controllers/test_slices_controller.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/controllers/test_slices_controller.rb b/test/controllers/test_slices_controller.rb index e1250ba2b..f4e3193ea 100644 --- a/test/controllers/test_slices_controller.rb +++ b/test/controllers/test_slices_controller.rb @@ -46,12 +46,18 @@ def test_create_slices post "/slices?apikey=#{@@user.apikey}", MultiJson.dump(@@new_slice_data), "CONTENT_TYPE" => "application/json" - assert 201, last_response.status + assert_equal 201, last_response.status + + # Verify created + get "/slices?apikey=#{@@user.apikey}" + assert_equal 200, last_response.status + slices = MultiJson.load(last_response.body) + assert_includes slices.map { |s| s["acronym"] }, @@new_slice_data[:acronym] end def test_delete_slices self.class.enable_security - LinkedData.settings.enable_security = @@old_security_setting + # LinkedData.settings.enable_security = @@old_security_setting self.class._create_slice(@@new_slice_data[:acronym], @@new_slice_data[:name], @@onts) @@ -61,7 +67,13 @@ def test_delete_slices self.class.make_admin(@@user) delete "/slices/#{@@new_slice_data[:acronym]}?apikey=#{@@user.apikey}" - assert 201, last_response.status + assert_equal 204, last_response.status + + # Verify deleted + get "/slices?apikey=#{@@user.apikey}" + assert_equal 200, last_response.status + slices = MultiJson.load(last_response.body) + refute_includes slices.map { |s| s["acronym"] }, @@new_slice_data[:acronym] end private From 291406bfe0b1f1642ef31a306c86ccf143b1e994 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 4 Nov 2025 13:11:02 -0800 Subject: [PATCH 015/173] test: fail fast on error payloads in bulk delete polling - Add explicit flunk when status_payload contains 'errors' to prevent false positives from incomplete or invalid responses - Ensure test fails immediately on backend error instead of silently skipping assertions --- .../test_ontology_submissions_controller.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 1d372ae7d..42d5214b2 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -181,13 +181,22 @@ def test_delete_ontology_submissions sleep 0.1 end - # Validate result payload when present - if status_payload["deleted_ids"] - # Only the chosen 5 should be deleted - assert_equal delete_ids, status_payload["deleted_ids"].map(&:to_i).sort, "Deleted IDs mismatch" + # Validate result payload + if status_payload["errors"] + flunk "Bulk delete returned errors: #{status_payload['errors'].inspect}" + else + returned_deleted = Array(status_payload["deleted_ids"]).map(&:to_i).sort + assert_equal delete_ids, returned_deleted, "Deleted IDs mismatch" assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") - end + end + # Validate result payload when present + # if status_payload["deleted_ids"] + # # Only the chosen 3 should be deleted + # assert_equal delete_ids, status_payload["deleted_ids"].map(&:to_i).sort, "Deleted IDs mismatch" + # assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" + # assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") + # end # Deleted ones should be gone delete_ids.each do |sid| From 1ffbf632dead86a7adb20445309f7d08c691ae8f Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 4 Nov 2025 22:44:59 -0800 Subject: [PATCH 016/173] Reset enable_slices in after_suite Restore LinkedData.settings.enable_slices to its original value after tests. --- test/helpers/test_slices_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/helpers/test_slices_helper.rb b/test/helpers/test_slices_helper.rb index e776c1551..9639c6b17 100644 --- a/test/helpers/test_slices_helper.rb +++ b/test/helpers/test_slices_helper.rb @@ -32,6 +32,7 @@ def before_suite end def after_suite + LinkedData.settings.enable_slices = @@orig_slices_setting self.backend_4s_delete end From fa6f603bf98c2213944ccb9d6acaf37ba668ed07 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 09:14:08 -0800 Subject: [PATCH 017/173] cleanup: remove dead code --- test/test_case.rb | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/test/test_case.rb b/test/test_case.rb index dba7d3270..48832c5b7 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -110,28 +110,7 @@ def after_all after_suite super end - - - - def _run_suite(suite, type) - begin - backend_4s_delete - suite.before_suite if suite.respond_to?(:before_suite) - super(suite, type) - rescue Exception => e - puts e.message - puts e.backtrace.join("\n\t") - puts "Traced from:" - raise e - ensure - backend_4s_delete - suite.after_suite if suite.respond_to?(:after_suite) - end - end end - - - # All tests should inherit from this class. # Use 'rake test' from the command line to run tests. # See http://www.sinatrarb.com/testing.html for testing information From cef113f9845757e975749d72a2a2bb90421e5149 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 10:35:47 -0800 Subject: [PATCH 018/173] test: use idiomatic Minitest assertions --- test/controllers/test_batch_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/test_batch_controller.rb b/test/controllers/test_batch_controller.rb index ca37b156e..492a608ff 100644 --- a/test/controllers/test_batch_controller.rb +++ b/test/controllers/test_batch_controller.rb @@ -49,7 +49,7 @@ def test_class_wrong_params } } post "/batch/", call_params - assert last_response.status = 422 + assert_equal 422, last_response.status end def test_class_batch_multiple @@ -109,7 +109,7 @@ def test_class_all_bro assert_equal classes.length, classes_response.length classes_response.each do |klass| assert_instance_of String, klass["prefLabel"] - assert klass["prefLabel"] == class_ids[klass["@id"]] + assert_equal klass["prefLabel"], class_ids[klass["@id"]] end end end From 7c774b0fddfaab62524c065450c71a1784e68c0a Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 10:37:39 -0800 Subject: [PATCH 019/173] test: remove binding.pry --- test/helpers/test_users_helper.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/helpers/test_users_helper.rb b/test/helpers/test_users_helper.rb index 9f1614f18..6ceb686f4 100644 --- a/test/helpers/test_users_helper.rb +++ b/test/helpers/test_users_helper.rb @@ -56,8 +56,6 @@ def test_search_custom_onts assert results.all? {|r| @@custom_ont_ids.include?(r["links"]["ontology"])} end - private - def self._create_user(username = nil) username ||= "testuser" u = LinkedData::Models::User.new({ @@ -65,7 +63,7 @@ def self._create_user(username = nil) email: "#{username}@example.com", password: "a_password" }) - u.save rescue binding.pry + u.save u end end From 08754e1fc041dcf407a55ef9c43fe64927a6e11d Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 10:41:39 -0800 Subject: [PATCH 020/173] cleanup: remove leftover commented-out code --- test/controllers/test_ontology_submissions_controller.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 42d5214b2..179edf450 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -190,13 +190,6 @@ def test_delete_ontology_submissions assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") end - # Validate result payload when present - # if status_payload["deleted_ids"] - # # Only the chosen 3 should be deleted - # assert_equal delete_ids, status_payload["deleted_ids"].map(&:to_i).sort, "Deleted IDs mismatch" - # assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" - # assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") - # end # Deleted ones should be gone delete_ids.each do |sid| From 9a905c15f907aea9a008acb43a32984b86d75f16 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 5 Nov 2025 13:39:03 -0800 Subject: [PATCH 021/173] added code to address random failures during unit test runs --- Gemfile | 3 +- Gemfile.lock | 55 +++++++++++-------- .../ontology_submissions_controller.rb | 2 +- helpers/application_helper.rb | 3 +- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/Gemfile b/Gemfile index 0289d404c..c0f5193f4 100644 --- a/Gemfile +++ b/Gemfile @@ -81,4 +81,5 @@ group :test do gem 'simplecov-cobertura' # for codecov.io gem 'webmock', '~> 3.19.1' gem 'webrick' -end + gem 'minitest-bisect' +end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index ac7c7e4da..9cdb7fce1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: c4f16085b3e34b1e38e30232988297016e1f0e39 + revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 branch: develop specs: ncbo_cron (0.0.1) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 + revision: e8980335667cfdf3687be0ce1adbeaa58c62e7c9 branch: develop specs: ontologies_linked_data (0.0.1) @@ -142,15 +142,16 @@ GEM rexml cube-ruby (0.0.3) dante (0.2.0) - date (3.4.1) + date (3.5.0) docile (1.4.1) domain_name (0.6.20240107) + drb (2.2.3) ed25519 (1.4.0) faraday (2.14.0) faraday-net_http (>= 2.0, < 3.5) json logger - faraday-follow_redirects (0.3.0) + faraday-follow_redirects (0.4.0) faraday (>= 1, < 3) faraday-net_http (3.4.1) net-http (>= 0.5.0) @@ -167,7 +168,7 @@ GEM ffi (1.17.2-x86_64-darwin) ffi (1.17.2-x86_64-linux-gnu) ffi (1.17.2-x86_64-linux-musl) - gapic-common (1.0.1) + gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) google-cloud-env (~> 2.2) @@ -179,7 +180,7 @@ GEM grpc (~> 1.66) get_process_mem (0.2.7) ffi (~> 1.0) - google-analytics-data (0.7.1) + google-analytics-data (0.7.2) google-analytics-data-v1beta (>= 0.11, < 2.a) google-cloud-core (~> 1.6) google-analytics-data-v1beta (0.17.0) @@ -205,39 +206,39 @@ GEM grpc (~> 1.41) googleapis-common-protos-types (1.20.0) google-protobuf (>= 3.18, < 5.a) - googleauth (1.14.0) + googleauth (1.15.1) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.2) google-logging-utils (~> 0.1) - jwt (>= 1.4, < 3.0) + jwt (>= 1.4, < 4.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - grpc (1.74.0) + grpc (1.76.0) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-aarch64-linux-gnu) + grpc (1.76.0-aarch64-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-aarch64-linux-musl) + grpc (1.76.0-aarch64-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-arm64-darwin) + grpc (1.76.0-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86-linux-gnu) + grpc (1.76.0-x86-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86-linux-musl) + grpc (1.76.0-x86-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-darwin) + grpc (1.76.0-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-linux-gnu) + grpc (1.76.0-x86_64-linux-gnu) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.74.0-x86_64-linux-musl) + grpc (1.76.0-x86_64-linux-musl) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) haml (5.2.2) @@ -253,7 +254,7 @@ GEM json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) - jwt (2.10.2) + jwt (3.1.2) base64 kgio (2.11.4) language_server-protocol (3.17.0.5) @@ -275,13 +276,19 @@ GEM mime-types-data (3.2025.0924) mini_mime (1.1.5) minitest (5.26.0) + minitest-bisect (1.7.0) + minitest-server (~> 1.0) + path_expander (~> 1.1) minitest-hooks (1.5.2) minitest (> 5.3) + minitest-server (1.0.8) + drb (~> 2.0) + minitest (~> 5.16) minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis multi_json (1.17.0) - net-ftp (0.3.8) + net-ftp (0.3.9) net-protocol time net-http (0.6.0) @@ -315,6 +322,7 @@ GEM parser (3.3.8.0) ast (~> 2.4.1) racc + path_expander (1.1.3) pony (1.13.1) mail (>= 2.0) prism (1.4.0) @@ -382,13 +390,13 @@ GEM prism (~> 1.4) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.2.1) + rubyzip (3.2.2) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) - signet (0.20.0) + signet (0.21.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 3.0) + jwt (>= 1.5, < 4.0) multi_json (~> 1.10) simplecov (0.22.0) docile (~> 1.1) @@ -425,7 +433,7 @@ GEM tilt (2.6.1) time (0.4.1) date - timeout (0.4.3) + timeout (0.4.4) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) @@ -479,6 +487,7 @@ DEPENDENCIES haml (~> 5.2.2) json-schema (~> 2.0) minitest (~> 5.0) + minitest-bisect minitest-hooks (~> 1.5) minitest-stub_any_instance multi_json diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index afe0e15cd..1b9463103 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -144,7 +144,7 @@ class OntologySubmissionsController < ApplicationController # Re-fetch ontology to avoid stale submissions cache ont_refreshed = Ontology.find(params["acronym"]).include(submissions: :submissionId).first new_latest_sub = ont_refreshed.latest_submission(status: :any) - NcboCron::Models::OntologySubmissionParser.new.queue_submission(new_latest_sub, all: true) if new_latest_sub + NcboCron::Models::OntologySubmissionParser.new.queue_submission(new_latest_sub, all: true) if new_latest_sub && ENV['RACK_ENV'] != 'test' end payload = { deleted_ids: deleted_ids, deleted_count: deleted_ids.size, missing_ids: missing } diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index f5d9ec782..e97366916 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -492,7 +492,8 @@ def process_long_operation(timeout, args = {}, &block) end # 4) Background work (toggle via fork: false in tests) - if args.fetch(:fork, true) + fork_process = ENV['RACK_ENV'] != 'test' + if fork_process pid = Process.fork { worker.call } Process.detach(pid) else From b395c482abb9e61923f10c118cbaf7cf265b387e Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 15:11:00 -0800 Subject: [PATCH 022/173] Gemfile.lock update --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9cdb7fce1..7ee73a860 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: e8980335667cfdf3687be0ce1adbeaa58c62e7c9 + revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 branch: develop specs: ontologies_linked_data (0.0.1) @@ -291,7 +291,7 @@ GEM net-ftp (0.3.9) net-protocol time - net-http (0.6.0) + net-http (0.7.0) uri net-http-persistent (2.9.4) net-imap (0.5.12) @@ -310,7 +310,7 @@ GEM net-ssh (7.3.0) netrc (0.11.0) newrelic_rpm (9.19.0) - oj (3.16.11) + oj (3.16.12) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -445,7 +445,7 @@ GEM unicorn-worker-killer (0.4.5) get_process_mem (~> 0) unicorn (>= 4, < 7) - uri (1.0.4) + uri (1.1.1) uuid (2.3.9) macaddr (~> 1.0) webmock (3.19.1) From ba9e9d98c062236d38934c8a0575560135a3edc0 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 21:40:15 -0800 Subject: [PATCH 023/173] test: remove suite globals in OntologySubmissions tests; add reusable user helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change refactors `TestOntologySubmissionsController` to eliminate suite-level globals and class-variable state in favor of per-test setup and shared helpers: - Replace `before_suite` + `@@acronym`/`@@name`/`@@file_params` with per-test `setup` that generates a unique ontology acronym and creates an ontology administered by a shared test user. - Introduce a suite-local `USERNAME = "test_user"` and use `ensure_user(USERNAME)` to guarantee the user exists without races. - Normalize assertion style: - Use `assert_equal(expected, actual, message)` with parentheses - Remove `msg=` pseudo-named args - Add `.sort` where appropriate when comparing unordered keys - Replace direct references to `@@acronym`/`@@name` with instance vars (`@acronym`, `@name`). New helper methods (in the base test class) used by this suite: - `create_user(username, email:, password:)` — always creates a user - `ensure_user(username, email:, password:)` — idempotently finds or creates - `delete_user(username)` — removes a user if present Notes: - `delete_ontologies_and_submissions` now runs in `setup` to guarantee a clean slate per test. `after_all` also cleans up the shared user via `delete_user(USERNAME)`. If the extra cleanup proves redundant, we can drop `before_all`/`after_all` and keep only the per-test cleanup. --- .../test_ontology_submissions_controller.rb | 158 ++++++++---------- test/test_case.rb | 15 ++ 2 files changed, 89 insertions(+), 84 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 179edf450..c7d5ea434 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -1,50 +1,40 @@ require_relative '../test_case' class TestOntologySubmissionsController < TestCase + USERNAME = "test_user".freeze - def before_suite - self.backend_4s_delete - self.class._set_vars - self.class._create_user - self.class._create_onts - end - - def self._set_vars - @@acronym = "TST" - @@name = "Test Ontology" - @@test_file = File.expand_path("../../data/ontology_files/BRO_v3.1.owl", __FILE__) - @@file_params = { - name: @@name, - hasOntologyLanguage: "OWL", - administeredBy: "tim", - "file" => Rack::Test::UploadedFile.new(@@test_file, ""), - released: DateTime.now.to_s, - contact: [{name: "test_name", email: "test3@example.org"}], - uri: 'https://test.com/test', - status: 'production', - description: 'ontology description' - } - @@status_uploaded = "UPLOADED" - @@status_rdf = "RDF" - end - - def self._create_user - username = "tim" - test_user = User.new(username: username, email: "#{username}@example.org", password: "password") - test_user.save if test_user.valid? - @@user = test_user.valid? ? test_user : User.find(username).first + def before_all + delete_ontologies_and_submissions + super end - def self._create_onts - ont = Ontology.new(acronym: @@acronym, name: @@name, administeredBy: [@@user]) - ont.save + def after_all + delete_ontologies_and_submissions + delete_user(USERNAME) end def setup delete_ontologies_and_submissions - ont = Ontology.new(acronym: @@acronym, name: @@name, administeredBy: [@@user]) - ont.save - end + @suffix = SecureRandom.hex(4) + @acronym = "TST#{@suffix}".upcase + @name = "Test Ontology #{@acronym}" + @user = ensure_user(USERNAME) + + Ontology.new(acronym: @acronym, name: @name, administeredBy: [@user]).save + + test_file = File.expand_path("../../data/ontology_files/BRO_v3.1.owl", __FILE__) + @file_params = { + name: @name, + hasOntologyLanguage: "OWL", + administeredBy: USERNAME, + "file" => Rack::Test::UploadedFile.new(test_file, ""), + released: Time.now.utc.iso8601, + contact: [{ name: "test_name", email: "test3@example.org" }], + uri: "https://test.com/test", + status: "production", + description: "ontology description" + } + end def test_submissions_for_given_ontology num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) @@ -59,30 +49,30 @@ def test_submissions_for_given_ontology end def test_create_new_submission_missing_file_and_pull_location - post "/ontologies/#{@@acronym}/submissions", name: @@name, hasOntologyLanguage: "OWL" - assert_equal(400, last_response.status, msg=get_errors(last_response)) + post "/ontologies/#{@acronym}/submissions", name: @name, hasOntologyLanguage: "OWL" + assert_equal(400, last_response.status, get_errors(last_response)) assert MultiJson.load(last_response.body)["errors"] end def test_create_new_submission_file - post "/ontologies/#{@@acronym}/submissions", @@file_params - assert_equal(201, last_response.status, msg=get_errors(last_response)) + post "/ontologies/#{@acronym}/submissions", @file_params + assert_equal(201, last_response.status, get_errors(last_response)) sub = MultiJson.load(last_response.body) - get "/ontologies/#{@@acronym}" + get "/ontologies/#{@acronym}" ont = MultiJson.load(last_response.body) - assert_equal @@acronym, ont["acronym"] + assert_equal @acronym, ont["acronym"] # Cleanup - delete "/ontologies/#{@@acronym}/submissions/#{sub['submissionId']}" - assert_equal(204, last_response.status, msg=get_errors(last_response)) + delete "/ontologies/#{@acronym}/submissions/#{sub['submissionId']}" + assert_equal(204, last_response.status, get_errors(last_response)) end def test_create_new_ontology_submission - post "/ontologies/#{@@acronym}/submissions", @@file_params - assert_equal(201, last_response.status, msg=get_errors(last_response)) + post "/ontologies/#{@acronym}/submissions", @file_params + assert_equal(201, last_response.status, get_errors(last_response)) # Cleanup sub = MultiJson.load(last_response.body) - delete "/ontologies/#{@@acronym}/submissions/#{sub['submissionId']}" - assert_equal(204, last_response.status, msg=get_errors(last_response)) + delete "/ontologies/#{@acronym}/submissions/#{sub['submissionId']}" + assert_equal(204, last_response.status, get_errors(last_response)) end def test_patch_ontology_submission @@ -92,7 +82,7 @@ def test_patch_ontology_submission submission = ont.submissions[0] new_values = {description: "Testing new description changes"} patch "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}", MultiJson.dump(new_values), "CONTENT_TYPE" => "application/json" - assert_equal(204, last_response.status, msg=get_errors(last_response)) + assert_equal(204, last_response.status, get_errors(last_response)) get "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}" submission = MultiJson.load(last_response.body) assert_equal "Testing new description changes", submission["description"] @@ -133,10 +123,10 @@ def test_delete_ontology_submission acronym = created_ont_acronyms.first submission_to_delete = (1..5).to_a.shuffle.first delete "/ontologies/#{acronym}/submissions/#{submission_to_delete}" - assert_equal(204, last_response.status, msg=get_errors(last_response)) + assert_equal(204, last_response.status, get_errors(last_response)) get "/ontologies/#{acronym}/submissions/#{submission_to_delete}" - assert_equal(404, last_response.status, msg=get_errors(last_response)) + assert_equal(404, last_response.status, get_errors(last_response)) end def test_delete_ontology_submissions @@ -157,7 +147,7 @@ def test_delete_ontology_submissions payload = MultiJson.dump({ ontology_submission_ids: delete_ids }) delete "/ontologies/#{acronym}/submissions", payload, "CONTENT_TYPE" => "application/json" - assert_equal 202, last_response.status, msg=get_errors(last_response) + assert_equal(202, last_response.status, get_errors(last_response)) body = MultiJson.load(last_response.body) process_id = body["process_id"] assert process_id, "Expected process_id in response for bulk delete" @@ -169,13 +159,13 @@ def test_delete_ontology_submissions loop do get "/ontologies/#{acronym}/submissions/bulk_delete/#{process_id}" - assert_equal 200, last_response.status, msg=get_errors(last_response) + assert_equal(200, last_response.status, get_errors(last_response)) status_payload = MultiJson.load(last_response.body) status = status_payload.is_a?(Hash) ? status_payload["status"] : nil has_errors = status_payload.is_a?(Hash) && status_payload["errors"] break if status == "done" || has_errors - + attempts += 1 assert attempts < max_attempts, "Timed out waiting for bulk delete to finish" sleep 0.1 @@ -186,21 +176,21 @@ def test_delete_ontology_submissions flunk "Bulk delete returned errors: #{status_payload['errors'].inspect}" else returned_deleted = Array(status_payload["deleted_ids"]).map(&:to_i).sort - assert_equal delete_ids, returned_deleted, "Deleted IDs mismatch" - assert_equal delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch" + assert_equal(delete_ids, returned_deleted, "Deleted IDs mismatch") + assert_equal(delete_ids.size, status_payload["deleted_count"], "Deleted count mismatch") assert(status_payload["missing_ids"].nil? || status_payload["missing_ids"].empty?, "Expected no missing IDs") - end + end # Deleted ones should be gone delete_ids.each do |sid| get "/ontologies/#{acronym}/submissions/#{sid}" - assert_equal 404, last_response.status, "Submission #{sid} should be gone, but GET returned #{last_response.status} for #{sid}" + assert_equal(404, last_response.status, "Submission #{sid} should be gone, but GET returned #{last_response.status} for #{sid}") end # Kept ones should still be present keep_ids.each do |sid| get "/ontologies/#{acronym}/submissions/#{sid}" - assert last_response.ok?, "Submission #{sid} should still exist, but GET returned #{last_response.status}" + assert(last_response.ok?, "Submission #{sid} should still exist, but GET returned #{last_response.status}") end end @@ -210,23 +200,23 @@ def test_download_submission assert_equal(1, onts.length, msg="Failed to create 1 ontology?") ont = onts.first ont.bring(:submissions, :acronym) - assert_instance_of(Ontology, ont, msg="ont is not a #{Ontology.class}") - assert_equal(1, ont.submissions.length, msg="Failed to create 1 ontology submission?") + assert_instance_of(Ontology, ont, "ont is not a #{Ontology.class}") + assert_equal(1, ont.submissions.length, "Failed to create 1 ontology submission?") sub = ont.submissions.first sub.bring(:submissionId) - assert_instance_of(OntologySubmission, sub, msg="sub is not a #{OntologySubmission.class}") + assert_instance_of(OntologySubmission, sub, "sub is not a #{OntologySubmission.class}") # Clear restrictions on downloads LinkedData::OntologiesAPI.settings.restrict_download = [] # Download the specific submission get "/ontologies/#{ont.acronym}/submissions/#{sub.submissionId}/download" - assert_equal(200, last_response.status, msg='failed download for specific submission : ' + get_errors(last_response)) + assert_equal(200, last_response.status, 'failed download for specific submission : ' + get_errors(last_response)) # Add restriction on download acronym = created_ont_acronyms.first LinkedData::OntologiesAPI.settings.restrict_download = [acronym] # Try download get "/ontologies/#{ont.acronym}/submissions/#{sub.submissionId}/download" # download should fail with a 403 status - assert_equal(403, last_response.status, msg='failed to restrict download for ontology : ' + get_errors(last_response)) + assert_equal(403, last_response.status, 'failed to restrict download for ontology : ' + get_errors(last_response)) # Clear restrictions on downloads LinkedData::OntologiesAPI.settings.restrict_download = [] # see also test_ontologies_controller::test_download_ontology @@ -243,11 +233,11 @@ def test_download_ontology_submission_rdf sub = ont.submissions.first get "/ontologies/#{acronym}/submissions/#{sub.submissionId}/download?download_format=rdf" - assert_equal(200, last_response.status, msg="Download failure for '#{acronym}' ontology: " + get_errors(last_response)) + assert_equal(200, last_response.status, "Download failure for '#{acronym}' ontology: " + get_errors(last_response)) # Download should fail with a 400 status. get "/ontologies/#{acronym}/submissions/#{sub.submissionId}/download?download_format=csr" - assert_equal(400, last_response.status, msg="Download failure for '#{acronym}' ontology: " + get_errors(last_response)) + assert_equal(400, last_response.status, "Download failure for '#{acronym}' ontology: " + get_errors(last_response)) end def test_download_acl_only @@ -279,15 +269,15 @@ def test_download_acl_only LinkedData.settings.enable_security = true get "/ontologies/#{acronym}/submissions/#{sub.submissionId}/download?apikey=#{allowed_user.apikey}" - assert_equal(200, last_response.status, msg="User who is in ACL couldn't download ontology") + assert_equal(200, last_response.status, "User who is in ACL couldn't download ontology") get "/ontologies/#{acronym}/submissions/#{sub.submissionId}/download?apikey=#{blocked_user.apikey}" - assert_equal(403, last_response.status, msg="User who isn't in ACL could download ontology") + assert_equal(403, last_response.status, "User who isn't in ACL could download ontology") admin = ont.administeredBy.first admin.bring(:apikey) get "/ontologies/#{acronym}/submissions/#{sub.submissionId}/download?apikey=#{admin.apikey}" - assert_equal(200, last_response.status, msg="Admin couldn't download ontology") + assert_equal(200, last_response.status, "Admin couldn't download ontology") ensure LinkedData.settings.enable_security = false del = User.find("allowed").first @@ -304,7 +294,7 @@ def test_submissions_default_includes submission_default_attributes = LinkedData::Models::OntologySubmission.hypermedia_settings[:serialize_default].map(&:to_s) get("/submissions?display_links=false&display_context=false&include_status=ANY") - assert last_response.ok? + assert(last_response.ok?) submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size @@ -316,9 +306,9 @@ def test_submissions_default_includes assert last_response.ok? submissions = MultiJson.load(last_response.body) - assert_equal 1, submissions.size + assert_equal(1, submissions.size) submissions.each do |sub| - assert_equal(submission_default_attributes, submission_keys(sub)) + assert_equal(submission_default_attributes.sort, submission_keys(sub).sort) end end @@ -333,9 +323,9 @@ def submission_all_attributes end get("/submissions?include=all&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) submissions = MultiJson.load(last_response.body) - assert_equal ontology_count, submissions.size + assert_equal(ontology_count, submissions.size) submissions.each do |sub| assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) @@ -344,9 +334,9 @@ def submission_all_attributes get("/ontologies/#{created_ont_acronyms.first}/submissions?include=all&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) submissions = MultiJson.load(last_response.body) - assert_equal 1, submissions.size + assert_equal(1, submissions.size) submissions.each do |sub| assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) @@ -354,14 +344,14 @@ def submission_all_attributes end get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=all&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) sub = MultiJson.load(last_response.body) assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) assert_submission_contact_structure(sub) get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=all&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) sub = MultiJson.load(last_response.body) assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) @@ -375,7 +365,7 @@ def test_submissions_custom_includes get("/submissions?include=#{include}&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size submissions.each do |sub| @@ -385,22 +375,22 @@ def test_submissions_custom_includes get("/ontologies/#{created_ont_acronyms.first}/submissions?include=#{include}&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) submissions = MultiJson.load(last_response.body) - assert_equal 1, submissions.size + assert_equal(1, submissions.size) submissions.each do |sub| assert_equal(include.split(','), submission_keys(sub)) assert_submission_contact_structure(sub) end get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=#{include}&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) sub = MultiJson.load(last_response.body) assert_equal(include.split(','), submission_keys(sub)) assert_submission_contact_structure(sub) get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=#{include}&display_links=false&display_context=false") - assert last_response.ok? + assert(last_response.ok?) sub = MultiJson.load(last_response.body) assert_equal(include.split(','), submission_keys(sub)) assert_submission_contact_structure(sub) diff --git a/test/test_case.rb b/test/test_case.rb index 48832c5b7..5e8265b84 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -191,6 +191,21 @@ def self.reset_security(old_security = @@old_security_setting) LinkedData.settings.enable_security = old_security end + # Ensure a user exists; return it. Safe to call from anywhere. + def create_user(username, email: nil, password: "password") + user = User.new(username: username, email: email || "#{username}@example.org", password: password) + user.save if user.valid? + user + end + + def ensure_user(username, email: nil, password: "password") + User.find(username).first || create_user(username, email: email, password: password) + end + + def delete_user(username) + User.find(username).first&.delete + end + def self.make_admin(user) user.bring_remaining From 1036e0e0766f925655dc618a9317c4a6c95d7141 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 5 Nov 2025 23:37:48 -0800 Subject: [PATCH 024/173] tests: remove custom user creation/deletion, rely on default factory user --- .../test_ontology_submissions_controller.rb | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index c7d5ea434..b9c198ffc 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -1,15 +1,8 @@ require_relative '../test_case' class TestOntologySubmissionsController < TestCase - USERNAME = "test_user".freeze - - def before_all - delete_ontologies_and_submissions - super - end def after_all delete_ontologies_and_submissions - delete_user(USERNAME) end def setup @@ -18,15 +11,15 @@ def setup @suffix = SecureRandom.hex(4) @acronym = "TST#{@suffix}".upcase @name = "Test Ontology #{@acronym}" - @user = ensure_user(USERNAME) + @test_user, _format, _contact = LinkedData::SampleData::Ontology.ontology_objects - Ontology.new(acronym: @acronym, name: @name, administeredBy: [@user]).save + Ontology.new(acronym: @acronym, name: @name, administeredBy: [@test_user]).save test_file = File.expand_path("../../data/ontology_files/BRO_v3.1.owl", __FILE__) @file_params = { name: @name, hasOntologyLanguage: "OWL", - administeredBy: USERNAME, + administeredBy: @test_user, "file" => Rack::Test::UploadedFile.new(test_file, ""), released: Time.now.utc.iso8601, contact: [{ name: "test_name", email: "test3@example.org" }], @@ -104,18 +97,18 @@ def test_patch_submission_ignores_system_controlled_attributes patch "/ontologies/#{acronym}/submissions/#{submission.submissionId}", MultiJson.dump(patch_payload), "CONTENT_TYPE" => "application/json" - assert_equal 204, last_response.status + assert_equal(204, last_response.status, get_errors(last_response)) get "/ontologies/#{acronym}/submissions/#{submission.submissionId}" updated_submission = MultiJson.load(last_response.body) # Confirm description was updated - assert_equal "Updated description", updated_submission["description"] + assert_equal("Updated description", updated_submission["description"]) # Confirm restricted fields were ignored - refute_includes updated_submission, "uploadFilePath" - refute_includes updated_submission, "diffFilePath" - refute_includes updated_submission, "missingImports" + refute_includes(updated_submission, "uploadFilePath") + refute_includes(updated_submission, "diffFilePath") + refute_includes(updated_submission, "missingImports") end def test_delete_ontology_submission From 1392b8824f93f6cceb1853b9068513506d65da09 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 7 Nov 2025 08:57:54 -0800 Subject: [PATCH 025/173] chore(style) fix RuboCop offences --- .../test_ontology_submissions_controller.rb | 95 ++++++++++--------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index b9c198ffc..3a5712f15 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -1,6 +1,5 @@ -require_relative '../test_case' +require_relative "../test_case" class TestOntologySubmissionsController < TestCase - def after_all delete_ontologies_and_submissions end @@ -8,21 +7,21 @@ def after_all def setup delete_ontologies_and_submissions - @suffix = SecureRandom.hex(4) - @acronym = "TST#{@suffix}".upcase - @name = "Test Ontology #{@acronym}" + @suffix = SecureRandom.hex(4) + @acronym = "TST#{@suffix}".upcase + @name = "Test Ontology #{@acronym}" @test_user, _format, _contact = LinkedData::SampleData::Ontology.ontology_objects Ontology.new(acronym: @acronym, name: @name, administeredBy: [@test_user]).save - test_file = File.expand_path("../../data/ontology_files/BRO_v3.1.owl", __FILE__) + test_file = File.expand_path("../data/ontology_files/BRO_v3.1.owl", __dir__) @file_params = { name: @name, hasOntologyLanguage: "OWL", administeredBy: @test_user, - "file" => Rack::Test::UploadedFile.new(test_file, ""), + file: Rack::Test::UploadedFile.new(test_file, ""), released: Time.now.utc.iso8601, - contact: [{ name: "test_name", email: "test3@example.org" }], + contact: [{name: "test_name", email: "test3@example.org"}], uri: "https://test.com/test", status: "production", description: "ontology description" @@ -35,7 +34,7 @@ def test_submissions_for_given_ontology get "/ontologies/#{ontology}/submissions" assert last_response.ok? - submissions_goo = OntologySubmission.where(ontology: { acronym: ontology}).to_a + submissions_goo = OntologySubmission.where(ontology: {acronym: ontology}).to_a submissions = MultiJson.load(last_response.body) assert_equal submissions.length, submissions_goo.length @@ -55,7 +54,7 @@ def test_create_new_submission_file ont = MultiJson.load(last_response.body) assert_equal @acronym, ont["acronym"] # Cleanup - delete "/ontologies/#{@acronym}/submissions/#{sub['submissionId']}" + delete "/ontologies/#{@acronym}/submissions/#{sub["submissionId"]}" assert_equal(204, last_response.status, get_errors(last_response)) end @@ -64,17 +63,18 @@ def test_create_new_ontology_submission assert_equal(201, last_response.status, get_errors(last_response)) # Cleanup sub = MultiJson.load(last_response.body) - delete "/ontologies/#{@acronym}/submissions/#{sub['submissionId']}" + delete "/ontologies/#{@acronym}/submissions/#{sub["submissionId"]}" assert_equal(204, last_response.status, get_errors(last_response)) end def test_patch_ontology_submission num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) - ont = Ontology.find(created_ont_acronyms.first).include(submissions: [:submissionId, ontology: :acronym]).first + ont = Ontology.find(created_ont_acronyms.first).include(submissions: [:submissionId, {ontology: :acronym}]).first assert_operator ont.submissions.length, :>, 0 submission = ont.submissions[0] new_values = {description: "Testing new description changes"} - patch "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}", MultiJson.dump(new_values), "CONTENT_TYPE" => "application/json" + patch "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}", + MultiJson.dump(new_values), "CONTENT_TYPE" => "application/json" assert_equal(204, last_response.status, get_errors(last_response)) get "/ontologies/#{submission.ontology.acronym}/submissions/#{submission.submissionId}" submission = MultiJson.load(last_response.body) @@ -84,7 +84,7 @@ def test_patch_ontology_submission def test_patch_submission_ignores_system_controlled_attributes _, acronyms = create_ontologies_and_submissions(ont_count: 1) acronym = acronyms.first - ontology = Ontology.find(acronym).include(submissions: [:submissionId, ontology: :acronym]).first + ontology = Ontology.find(acronym).include(submissions: [:submissionId, {ontology: :acronym}]).first assert_operator ontology.submissions.length, :>, 0 submission = ontology.submissions.first @@ -95,8 +95,8 @@ def test_patch_submission_ignores_system_controlled_attributes } patch "/ontologies/#{acronym}/submissions/#{submission.submissionId}", - MultiJson.dump(patch_payload), - "CONTENT_TYPE" => "application/json" + MultiJson.dump(patch_payload), + "CONTENT_TYPE" => "application/json" assert_equal(204, last_response.status, get_errors(last_response)) get "/ontologies/#{acronym}/submissions/#{submission.submissionId}" @@ -112,9 +112,10 @@ def test_patch_submission_ignores_system_controlled_attributes end def test_delete_ontology_submission - num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1, random_submission_count: false, submission_count: 5) + num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1, + random_submission_count: false, submission_count: 5) acronym = created_ont_acronyms.first - submission_to_delete = (1..5).to_a.shuffle.first + submission_to_delete = (1..5).to_a.sample delete "/ontologies/#{acronym}/submissions/#{submission_to_delete}" assert_equal(204, last_response.status, get_errors(last_response)) @@ -137,7 +138,7 @@ def test_delete_ontology_submissions assert_equal submission_count - delete_ids.size, keep_ids.size, "Unexpected keep_ids size" # Kick off the long-running bulk delete via the collection DELETE endpoint - payload = MultiJson.dump({ ontology_submission_ids: delete_ids }) + payload = MultiJson.dump({ontology_submission_ids: delete_ids}) delete "/ontologies/#{acronym}/submissions", payload, "CONTENT_TYPE" => "application/json" assert_equal(202, last_response.status, get_errors(last_response)) @@ -164,9 +165,9 @@ def test_delete_ontology_submissions sleep 0.1 end - # Validate result payload + # Validate result payload if status_payload["errors"] - flunk "Bulk delete returned errors: #{status_payload['errors'].inspect}" + flunk "Bulk delete returned errors: #{status_payload["errors"].inspect}" else returned_deleted = Array(status_payload["deleted_ids"]).map(&:to_i).sort assert_equal(delete_ids, returned_deleted, "Deleted IDs mismatch") @@ -177,7 +178,8 @@ def test_delete_ontology_submissions # Deleted ones should be gone delete_ids.each do |sid| get "/ontologies/#{acronym}/submissions/#{sid}" - assert_equal(404, last_response.status, "Submission #{sid} should be gone, but GET returned #{last_response.status} for #{sid}") + assert_equal(404, last_response.status, + "Submission #{sid} should be gone, but GET returned #{last_response.status} for #{sid}") end # Kept ones should still be present @@ -188,9 +190,10 @@ def test_delete_ontology_submissions end def test_download_submission - num_onts_created, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: false) - assert_equal(1, num_onts_created, msg="Failed to create 1 ontology?") - assert_equal(1, onts.length, msg="Failed to create 1 ontology?") + num_onts_created, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, + process_submission: false) + assert_equal(1, num_onts_created, "Failed to create 1 ontology?") + assert_equal(1, onts.length, "Failed to create 1 ontology?") ont = onts.first ont.bring(:submissions, :acronym) assert_instance_of(Ontology, ont, "ont is not a #{Ontology.class}") @@ -202,25 +205,27 @@ def test_download_submission LinkedData::OntologiesAPI.settings.restrict_download = [] # Download the specific submission get "/ontologies/#{ont.acronym}/submissions/#{sub.submissionId}/download" - assert_equal(200, last_response.status, 'failed download for specific submission : ' + get_errors(last_response)) + assert_equal(200, last_response.status, "failed download for specific submission : " + get_errors(last_response)) # Add restriction on download acronym = created_ont_acronyms.first LinkedData::OntologiesAPI.settings.restrict_download = [acronym] # Try download get "/ontologies/#{ont.acronym}/submissions/#{sub.submissionId}/download" # download should fail with a 403 status - assert_equal(403, last_response.status, 'failed to restrict download for ontology : ' + get_errors(last_response)) + assert_equal(403, last_response.status, "failed to restrict download for ontology : " + get_errors(last_response)) # Clear restrictions on downloads LinkedData::OntologiesAPI.settings.restrict_download = [] # see also test_ontologies_controller::test_download_ontology # Test downloads of nonexistent ontology get "/ontologies/BOGUS66/submissions/55/download" - assert_equal(422, last_response.status, "failed to handle downloads of nonexistent ontology" + get_errors(last_response)) + assert_equal(422, last_response.status, + "failed to handle downloads of nonexistent ontology" + get_errors(last_response)) end def test_download_ontology_submission_rdf - count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: true) + count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, + process_submission: true) acronym = created_ont_acronyms.first ont = onts.first sub = ont.submissions.first @@ -234,7 +239,8 @@ def test_download_ontology_submission_rdf end def test_download_acl_only - count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: false) + count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, + process_submission: false) acronym = created_ont_acronyms.first ont = onts.first.bring_remaining ont.bring(:submissions) @@ -282,7 +288,8 @@ def test_download_acl_only def test_submissions_default_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) + num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + submission_count: 1, submissions_to_process: []) submission_default_attributes = LinkedData::Models::OntologySubmission.hypermedia_settings[:serialize_default].map(&:to_s) @@ -307,10 +314,11 @@ def test_submissions_default_includes def test_submissions_all_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) + num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + submission_count: 1, submissions_to_process: []) def submission_all_attributes attrs = OntologySubmission.goo_attrs_to_load([:all]) - embed_attrs = attrs.select { |x| x.is_a?(Hash) }.first + embed_attrs = attrs.find { |x| x.is_a?(Hash) } attrs.delete_if { |x| x.is_a?(Hash) }.map(&:to_s) + embed_attrs.keys.map(&:to_s) end @@ -353,8 +361,9 @@ def submission_all_attributes def test_submissions_custom_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) - include = 'ontology,contact,submissionId' + num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + submission_count: 1, submissions_to_process: []) + include = "ontology,contact,submissionId" get("/submissions?include=#{include}&display_links=false&display_context=false") @@ -362,7 +371,7 @@ def test_submissions_custom_includes submissions = MultiJson.load(last_response.body) assert_equal ontology_count, submissions.size submissions.each do |sub| - assert_equal(include.split(','), submission_keys(sub)) + assert_equal(include.split(","), submission_keys(sub)) assert_submission_contact_structure(sub) end @@ -372,33 +381,33 @@ def test_submissions_custom_includes submissions = MultiJson.load(last_response.body) assert_equal(1, submissions.size) submissions.each do |sub| - assert_equal(include.split(','), submission_keys(sub)) + assert_equal(include.split(","), submission_keys(sub)) assert_submission_contact_structure(sub) end get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=#{include}&display_links=false&display_context=false") assert(last_response.ok?) sub = MultiJson.load(last_response.body) - assert_equal(include.split(','), submission_keys(sub)) + assert_equal(include.split(","), submission_keys(sub)) assert_submission_contact_structure(sub) get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=#{include}&display_links=false&display_context=false") assert(last_response.ok?) sub = MultiJson.load(last_response.body) - assert_equal(include.split(','), submission_keys(sub)) + assert_equal(include.split(","), submission_keys(sub)) assert_submission_contact_structure(sub) end private + def submission_keys(sub) sub.to_hash.keys - %w[@id @type id] end def assert_submission_contact_structure(sub) assert sub["contact"], "Contact should be present" - if sub["contact"].first - assert_equal(%w[name email id].sort, sub["contact"].first.keys.sort) - end - end + return unless sub["contact"].first + assert_equal(%w[name email id].sort, sub["contact"].first.keys.sort) + end end From 4cabfcd2e07daf503825ada995b83a6cd89fb06d Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 12 Nov 2025 11:22:28 -0800 Subject: [PATCH 026/173] reset branch specifier to master --- Gemfile | 12 ++++++------ Gemfile.lock | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Gemfile b/Gemfile index c0f5193f4..069ba56b6 100644 --- a/Gemfile +++ b/Gemfile @@ -43,11 +43,11 @@ gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 gem 'redcarpet' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'develop' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'master' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' group :development do @@ -82,4 +82,4 @@ group :test do gem 'webmock', '~> 3.19.1' gem 'webrick' gem 'minitest-bisect' -end \ No newline at end of file +end diff --git a/Gemfile.lock b/Gemfile.lock index 7ee73a860..6fed911a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/ncbo/goo.git - revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c - branch: develop + revision: 5cac44e06a6bf0c093563dad66240ab07fec4d9c + branch: master specs: goo (0.0.2) addressable (~> 2.8) @@ -16,8 +16,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 55e8cbfac358b2c40deb0bd963bfe6dee91e8347 - branch: develop + revision: 4fb9114b80b99f0a654c7f70aaa96839c74fc615 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -27,8 +27,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 - branch: develop + revision: 7ee2651664e411945c878133073351f817ff6b8d + branch: master specs: ncbo_cron (0.0.1) dante @@ -45,8 +45,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 76d9516adc3c5c6d5c95f21f307bdd60eb3e0acd - branch: develop + revision: c6a18eb7700b23a1a4f1e32ebc94003bf75efe93 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -56,8 +56,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 - branch: develop + revision: 1a6d42628cfcf1704b96de45e27e81392333e343 + branch: master specs: ontologies_linked_data (0.0.1) activesupport From e3e983d621ad0ba03865059c76e9f64dd98c9929 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 16 Dec 2025 13:35:47 -0800 Subject: [PATCH 027/173] addressed a minor vulnerability with ontology processing logs --- Gemfile.lock | 12 ++++++------ controllers/ontologies_controller.rb | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7ee73a860..e52c66683 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c + revision: 68f4613039cd088b236f3c8b1a8e832e7acce138 branch: develop specs: goo (0.0.2) @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 + revision: d3625bc7769f1c8cfcc4063ac9478b0723ed4686 branch: develop specs: ncbo_cron (0.0.1) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 + revision: 73b4f60deb65528b3fe8de928b78cabd6276f6b8 branch: develop specs: ontologies_linked_data (0.0.1) @@ -153,8 +153,8 @@ GEM logger faraday-follow_redirects (0.4.0) faraday (>= 1, < 3) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) + faraday-net_http (3.4.2) + net-http (~> 0.5) faraday-retry (2.3.2) faraday (~> 2.0) ffi (1.17.2) @@ -433,7 +433,7 @@ GEM tilt (2.6.1) time (0.4.1) date - timeout (0.4.4) + timeout (0.5.0) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) diff --git a/controllers/ontologies_controller.rb b/controllers/ontologies_controller.rb index a8abcb327..5405410e3 100644 --- a/controllers/ontologies_controller.rb +++ b/controllers/ontologies_controller.rb @@ -189,7 +189,7 @@ def create_ontology ont.bring(:viewingRestriction) ont.bring(:administeredBy) ont.bring(:acl) - check_access(ont) + check_write_access(ont) latest_any = ont.latest_submission(status: :any) if latest_any From 03067382fd545eb9d8e3fcbe62875daa5d824126 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 16 Dec 2025 15:55:14 -0800 Subject: [PATCH 028/173] reverted Gemfile.lock --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e52c66683..7ee73a860 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 68f4613039cd088b236f3c8b1a8e832e7acce138 + revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c branch: develop specs: goo (0.0.2) @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: d3625bc7769f1c8cfcc4063ac9478b0723ed4686 + revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 branch: develop specs: ncbo_cron (0.0.1) @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 73b4f60deb65528b3fe8de928b78cabd6276f6b8 + revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 branch: develop specs: ontologies_linked_data (0.0.1) @@ -153,8 +153,8 @@ GEM logger faraday-follow_redirects (0.4.0) faraday (>= 1, < 3) - faraday-net_http (3.4.2) - net-http (~> 0.5) + faraday-net_http (3.4.1) + net-http (>= 0.5.0) faraday-retry (2.3.2) faraday (~> 2.0) ffi (1.17.2) @@ -433,7 +433,7 @@ GEM tilt (2.6.1) time (0.4.1) date - timeout (0.5.0) + timeout (0.4.4) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) From 52f4bbfdfff89d43417357140498509de90f0a51 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 17 Dec 2025 10:06:53 -0800 Subject: [PATCH 029/173] CI: Refactor deployment workflow (#201) Refactor deployment workflow: safer permissions, better triggers, and concurrency lock - use minimal token permissions - Auto-deploy only from develop - global concurrency lock - Improve BRANCH/TARGET logic - Add deployment detail output --- .github/workflows/deploy.yml | 71 ++++++++++++++++++++++++------------ Gemfile | 12 +++--- Gemfile.lock | 20 +++++----- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3f0f0d75c..6cab3db44 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,25 +14,22 @@ # # DEPLOY_ENC_KEY - key for decrypting deploymnet ssh key residing in config/deploy_id_rsa_enc (see miloserdow/capistrano-deploy) # this SSH key is used for accessing jump host, UI nodes, and private github repo. - name: Capistrano Deployment -# Controls when the action will run. + +permissions: + contents: read + on: - push: - branches: - - master - - develop # Trigger deployment to staging after unit test action completes workflow_run: workflows: ["Ruby Unit Tests"] types: - completed - branches: [master, develop] + branches: [develop] # trigger auto deployment to staging from develop branch # Allows running this workflow manually from the Actions tab workflow_dispatch: - branches: [master, develop] inputs: - BRANCH: + branch: description: 'Branch/tag to deploy' default: develop required: true @@ -46,36 +43,62 @@ on: jobs: deploy: + concurrency: + group: deploy runs-on: ubuntu-latest - # run deployment only if "Ruby Unit Tests" workflow completes sucessefully or when manually triggered - if: ${{ (github.event.workflow_run.conclusion == 'success') || (github.event_name == 'workflow_dispatch') }} + # run deployment only if "Ruby Unit Tests" workflow completes sucessefully + # or when manually triggered + if: > + (github.event_name == 'workflow_run' && + github.event.workflow_run.conclusion == 'success') || + (github.event_name == 'workflow_dispatch') env: - BUNDLE_WITHOUT: default #install gems required primarily for the deployment in order to speed this workflow + BUNDLE_WITHOUT: default:test:development #install gems required primarily for the deployment in order to speed this workflow PRIVATE_CONFIG_REPO: ${{ format('git@github.com:{0}.git', secrets.CONFIG_REPO) }} - # Steps represent a sequence of tasks that will be executed as part of the job steps: - name: set branch/tag and environment to deploy from inputs run: | - # workflow_dispatch default input doesn't get set on push so we need to set defaults - # via shell parameter expansion - # https://dev.to/mrmike/github-action-handling-input-default-value-5f2g - USER_INPUT_BRANCH=${{ inputs.branch }} - echo "BRANCH=${USER_INPUT_BRANCH:-develop}" >> $GITHUB_ENV - USER_INPUT_ENVIRONMENT=${{ inputs.environment }} - echo "TARGET=${USER_INPUT_ENVIRONMENT:-staging}" >> $GITHUB_ENV + if [ "${{ github.event_name }}" = "workflow_run" ]; then + # Auto: always deploy develop to staging + echo "BRANCH=develop" >> "$GITHUB_ENV" + # echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> "$GITHUB_ENV" # auto deploy from branch if needed + echo "TARGET=staging" >> "$GITHUB_ENV" + else + # Manual: use inputs, with defaulting via parameter expansion + USER_INPUT_BRANCH=${{ inputs.branch }} + USER_INPUT_ENVIRONMENT=${{ inputs.environment }} + + echo "BRANCH=${USER_INPUT_BRANCH:-develop}" >> "$GITHUB_ENV" + echo "TARGET=${USER_INPUT_ENVIRONMENT:-staging}" >> "$GITHUB_ENV" + fi + - name: Provide deployment info + run: | + echo "=== Deployment Details ======================================" + echo "Time: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" + echo "Branch/Tag: ${BRANCH}" + echo "Environment: ${TARGET}" + echo "Commit: ${GITHUB_SHA}" + echo "Triggered by: ${GITHUB_ACTOR}" + echo "Event: ${GITHUB_EVENT_NAME}" + if [ "${GITHUB_EVENT_NAME}" = "workflow_run" ]; then + echo "Mode: auto-deploy from develop" + else + echo "Mode: manual deployment" + fi + echo "==============================================================" # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ruby/setup-ruby@v1 with: bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: get-deployment-config - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: ${{ secrets.CONFIG_REPO }} # repository containing deployment settings token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT - path: deploy_config + path: deploy_config - name: copy-deployment-config - run: cp -r deploy_config/ontologies_api/* . + run: cp -r deploy_config/ontologies_api/* . # add ssh hostkey so that capistrano doesn't complain - name: Add jumphost's hostkey to Known Hosts run: | diff --git a/Gemfile b/Gemfile index c0f5193f4..069ba56b6 100644 --- a/Gemfile +++ b/Gemfile @@ -43,11 +43,11 @@ gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 gem 'redcarpet' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'develop' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'master' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' group :development do @@ -82,4 +82,4 @@ group :test do gem 'webmock', '~> 3.19.1' gem 'webrick' gem 'minitest-bisect' -end \ No newline at end of file +end diff --git a/Gemfile.lock b/Gemfile.lock index 7ee73a860..6fed911a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/ncbo/goo.git - revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c - branch: develop + revision: 5cac44e06a6bf0c093563dad66240ab07fec4d9c + branch: master specs: goo (0.0.2) addressable (~> 2.8) @@ -16,8 +16,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 55e8cbfac358b2c40deb0bd963bfe6dee91e8347 - branch: develop + revision: 4fb9114b80b99f0a654c7f70aaa96839c74fc615 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -27,8 +27,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 - branch: develop + revision: 7ee2651664e411945c878133073351f817ff6b8d + branch: master specs: ncbo_cron (0.0.1) dante @@ -45,8 +45,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 76d9516adc3c5c6d5c95f21f307bdd60eb3e0acd - branch: develop + revision: c6a18eb7700b23a1a4f1e32ebc94003bf75efe93 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -56,8 +56,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 - branch: develop + revision: 1a6d42628cfcf1704b96de45e27e81392333e343 + branch: master specs: ontologies_linked_data (0.0.1) activesupport From 5da0737fa117f5e81b16bdf40a19ad2db90a7546 Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 22 Jan 2026 22:48:37 -0800 Subject: [PATCH 030/173] initial commit, work-in-progress: sinatra 4.2.1 compatibiity --- .ruby-version | 2 +- Gemfile | 52 +- Gemfile.lock | 386 +++-- Rakefile | 5 + app.rb | 7 +- config/deploy.rb | 5 +- config/environments/config.rb.sample | 4 +- config/environments/test.rb | 6 +- config/logging.rb | 28 +- config/solr/property_search/enumsconfig.xml | 12 - .../mapping-ISOLatin1Accent.txt | 246 ---- config/solr/property_search/schema.xml | 1179 --------------- config/solr/property_search/solrconfig.xml | 1299 ----------------- config/solr/solr.xml | 60 - config/solr/term_search/enumsconfig.xml | 12 - .../term_search/mapping-ISOLatin1Accent.txt | 246 ---- config/solr/term_search/schema.xml | 1224 ---------------- config/solr/term_search/solrconfig.xml | 1299 ----------------- controllers/home_controller.rb | 1 - controllers/notes_controller.rb | 12 +- controllers/properties_search_controller.rb | 4 +- controllers/replies_controller.rb | 2 +- helpers/application_helper.rb | 16 +- init.rb | 48 +- .../test_properties_search_controller.rb | 4 +- test/controllers/test_search_controller.rb | 4 + test/helpers/test_slices_helper.rb | 1 + test/test_case.rb | 32 +- 28 files changed, 361 insertions(+), 5835 deletions(-) delete mode 100644 config/solr/property_search/enumsconfig.xml delete mode 100644 config/solr/property_search/mapping-ISOLatin1Accent.txt delete mode 100644 config/solr/property_search/schema.xml delete mode 100644 config/solr/property_search/solrconfig.xml delete mode 100644 config/solr/solr.xml delete mode 100644 config/solr/term_search/enumsconfig.xml delete mode 100644 config/solr/term_search/mapping-ISOLatin1Accent.txt delete mode 100644 config/solr/term_search/schema.xml delete mode 100644 config/solr/term_search/solrconfig.xml diff --git a/.ruby-version b/.ruby-version index 9cec7165a..be94e6f53 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.6 +3.2.2 diff --git a/Gemfile b/Gemfile index c0f5193f4..5514e55a6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,34 +1,44 @@ source 'https://rubygems.org' -gem 'activesupport', '~> 5' +gem 'activesupport' # see https://github.com/ncbo/ontologies_api/issues/69 gem 'bigdecimal' -# gem 'faraday', '~> 1.9' -gem 'json-schema', '~> 2.0' +gem 'json-schema' gem 'multi_json' gem 'oj' gem 'parseconfig' gem 'rack' -gem 'rake', '~> 10.0' +gem 'rake' gem 'rexml' # Investigate why unicorn fails to start under ruby 3 without adding rexml gem to the Gemfile -gem 'sinatra', '~> 1.0' -gem 'sinatra-advanced-routes' -gem 'sinatra-contrib', '~> 1.0' +gem 'rackup' +gem 'sinatra' + +github 'sinatra/sinatra' do + gem 'sinatra-contrib' +end + +gem 'request_store' +gem 'parallel' +gem 'google-protobuf', '3.25.3' +gem 'grpc', '1.70.1' +gem 'net-ftp' +gem 'json-ld', '~> 3.2.0' +gem 'rdf-raptor', github:'ruby-rdf/rdf-raptor', ref: '6392ceabf71c3233b0f7f0172f662bd4a22cd534' # use version 3.3.0 when available # Rack middleware gem 'ffi' -gem 'rack-accept', '~> 0.4' -gem 'rack-attack', '~> 6.6.1', require: 'rack/attack' -gem 'rack-cache', '~> 1.13.0' # see https://github.com/ncbo/ontologies_api/issues/118 +gem 'rack-accept' +gem 'rack-attack', require: 'rack/attack' +gem 'rack-cache' # see https://github.com/ncbo/ontologies_api/issues/118 gem 'rack-cors', require: 'rack/cors' # GitHub dependency can be removed when https://github.com/niko/rack-post-body-to-params/pull/6 is merged and released gem 'rack-post-body-to-params', github: 'palexander/rack-post-body-to-params', branch: 'multipart_support' gem 'rack-timeout' -gem 'redis-rack-cache', '~> 2.0' +gem 'redis-rack-cache' # Data access (caching) gem 'redis' -gem 'redis-store', '~>1.10' +gem 'redis-store' # Monitoring gem 'cube-ruby', require: 'cube' @@ -40,15 +50,16 @@ gem 'unicorn-worker-killer' # Templating gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 -gem 'redcarpet' +gem 'rack-contrib' +gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' -gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' group :development do # bcrypt_pbkdf and ed35519 is required for capistrano deployments when using ed25519 keys; see https://github.com/miloserdow/capistrano-deploy/issues/42 @@ -73,13 +84,14 @@ end group :test do gem 'byebug', '~> 12.0' gem 'crack', '0.4.5' - gem 'minitest', '~> 5.0' - gem 'minitest-hooks', "~> 1.5" + gem 'minitest' + gem 'minitest-hooks' gem 'minitest-stub_any_instance' + gem 'minitest-reporters' + gem 'minitest-fail-fast' gem 'rack-test' gem 'simplecov', require: false gem 'simplecov-cobertura' # for codecov.io - gem 'webmock', '~> 3.19.1' + gem 'webmock' gem 'webrick' - gem 'minitest-bisect' end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 7ee73a860..b37951f28 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,16 @@ GIT remote: https://github.com/ncbo/goo.git - revision: b92ae7ab3d2fad40a8b4a7563047c7157765472c - branch: develop + revision: edddd813a857446314a00d283d162c5ce53f945d + branch: ontoportal-lirmm-development specs: goo (0.0.2) addressable (~> 2.8) pry - rdf (= 1.0.8) + rdf + rdf-raptor + rdf-rdfxml + rdf-vocab redis - request_store rest-client rsolr sparql-client @@ -27,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 111c7263d8a98b1e8f7c033cb0b7d9c6cc10cd01 + revision: d3625bc7769f1c8cfcc4063ac9478b0723ed4686 branch: develop specs: ncbo_cron (0.0.1) @@ -56,12 +58,13 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9cae83def8a2a4a9bd1a3a1e8388c595c339ce72 - branch: develop + revision: ae232f1179efccad72f6d8284a539c7c8f818175 + branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) activesupport bcrypt + down (~> 5.0) goo json libxml-ruby @@ -77,13 +80,12 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git - revision: 512edc320b43e83971835dc046b4923485e8f70e - tag: v6.3.0 + revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 + branch: ontoportal-lirmm-development specs: - sparql-client (1.0.1) - json_pure (>= 1.4) - net-http-persistent (= 2.9.4) - rdf (>= 1.0) + sparql-client (3.2.2) + net-http-persistent (~> 4.0, >= 4.0.2) + rdf (~> 3.2, >= 3.2.11) GIT remote: https://github.com/palexander/rack-post-body-to-params.git @@ -101,34 +103,67 @@ GIT shotgun (0.9) rack (>= 1.0) +GIT + remote: https://github.com/ruby-rdf/rdf-raptor.git + revision: 6392ceabf71c3233b0f7f0172f662bd4a22cd534 + ref: 6392ceabf71c3233b0f7f0172f662bd4a22cd534 + specs: + rdf-raptor (3.3.0) + ffi (~> 1.15) + rdf (~> 3.3) + +GIT + remote: https://github.com/sinatra/sinatra.git + revision: 9e5c4ec8ade92c7375f44acf4c6e1103d32d6c12 + specs: + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + sinatra-contrib (4.2.1) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.2.1) + sinatra (= 4.2.1) + tilt (~> 2.0) + GEM remote: https://rubygems.org/ specs: - activesupport (5.2.8.1) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - airbrussh (1.5.3) + activesupport (8.1.2) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) + airbrussh (1.6.0) sshkit (>= 1.6.1, != 1.7.0) + ansi (1.5.0) ast (2.4.3) - backports (3.25.1) base64 (0.3.0) - bcrypt (3.1.20) - bcrypt_pbkdf (1.1.1) - bcrypt_pbkdf (1.1.1-arm64-darwin) - bcrypt_pbkdf (1.1.1-x86_64-darwin) - bigdecimal (3.3.1) + bcp47_spec (0.2.1) + bcrypt (3.1.21) + bcrypt_pbkdf (1.1.2) + bcrypt_pbkdf (1.1.2-arm64-darwin) + bcrypt_pbkdf (1.1.2-x86_64-darwin) + bigdecimal (4.0.1) builder (3.3.0) byebug (12.0.0) - capistrano (3.19.2) + capistrano (3.20.0) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) sshkit (>= 1.9.0) - capistrano-bundler (2.1.1) + capistrano-bundler (2.2.0) capistrano (~> 3.1) capistrano-locally (0.3.0) capistrano (~> 3.0) @@ -136,38 +171,40 @@ GEM capistrano (~> 3.1) sshkit (~> 1.3) coderay (1.1.3) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) crack (0.4.5) rexml cube-ruby (0.0.3) dante (0.2.0) - date (3.5.0) + date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) + down (5.4.2) + addressable (~> 2.8) drb (2.2.3) ed25519 (1.4.0) faraday (2.14.0) faraday-net_http (>= 2.0, < 3.5) json logger - faraday-follow_redirects (0.4.0) + faraday-follow_redirects (0.5.0) faraday (>= 1, < 3) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) - faraday-retry (2.3.2) + faraday-net_http (3.4.2) + net-http (~> 0.5) + faraday-retry (2.4.0) faraday (~> 2.0) - ffi (1.17.2) - ffi (1.17.2-aarch64-linux-gnu) - ffi (1.17.2-aarch64-linux-musl) - ffi (1.17.2-arm-linux-gnu) - ffi (1.17.2-arm-linux-musl) - ffi (1.17.2-arm64-darwin) - ffi (1.17.2-x86-linux-gnu) - ffi (1.17.2-x86-linux-musl) - ffi (1.17.2-x86_64-darwin) - ffi (1.17.2-x86_64-linux-gnu) - ffi (1.17.2-x86_64-linux-musl) + ffi (1.17.3) + ffi (1.17.3-aarch64-linux-gnu) + ffi (1.17.3-aarch64-linux-musl) + ffi (1.17.3-arm-linux-gnu) + ffi (1.17.3-arm-linux-musl) + ffi (1.17.3-arm64-darwin) + ffi (1.17.3-x86-linux-gnu) + ffi (1.17.3-x86-linux-musl) + ffi (1.17.3-x86_64-darwin) + ffi (1.17.3-x86_64-linux-gnu) + ffi (1.17.3-x86_64-linux-musl) gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) @@ -194,19 +231,19 @@ GEM faraday (>= 1.0, < 3.a) google-cloud-errors (1.5.0) google-logging-utils (0.2.0) - google-protobuf (3.25.8) - google-protobuf (3.25.8-aarch64-linux) - google-protobuf (3.25.8-arm64-darwin) - google-protobuf (3.25.8-x86-linux) - google-protobuf (3.25.8-x86_64-darwin) - google-protobuf (3.25.8-x86_64-linux) + google-protobuf (3.25.3) + google-protobuf (3.25.3-aarch64-linux) + google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86-linux) + google-protobuf (3.25.3-x86_64-darwin) + google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) google-protobuf (>= 3.18, < 5.a) googleapis-common-protos-types (~> 1.20) grpc (~> 1.41) googleapis-common-protos-types (1.20.0) google-protobuf (>= 3.18, < 5.a) - googleauth (1.15.1) + googleauth (1.16.1) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.2) google-logging-utils (~> 0.1) @@ -214,51 +251,53 @@ GEM multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - grpc (1.76.0) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-aarch64-linux-gnu) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-aarch64-linux-musl) + grpc (1.70.1) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-arm64-darwin) + grpc (1.70.1-aarch64-linux) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-x86-linux-gnu) + grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-x86-linux-musl) + grpc (1.70.1-x86-linux) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-x86_64-darwin) + grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-x86_64-linux-gnu) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) - grpc (1.76.0-x86_64-linux-musl) + grpc (1.70.1-x86_64-linux) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) haml (5.2.2) temple (>= 0.8.0) tilt - hashdiff (1.2.0) + hashdiff (1.2.1) + htmlentities (4.4.2) http-accept (1.7.0) http-cookie (1.1.0) domain_name (~> 0.5) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.15.2) - json-schema (2.8.1) - addressable (>= 2.4) - json_pure (2.8.1) + io-console (0.8.2) + json (2.18.0) + json-canonicalization (0.4.0) + json-ld (3.2.5) + htmlentities (~> 4.3) + json-canonicalization (~> 0.3, >= 0.3.2) + link_header (~> 0.0, >= 0.0.8) + multi_json (~> 1.15) + rack (>= 2.2, < 4) + rdf (~> 3.2, >= 3.2.10) + json-schema (6.1.0) + addressable (~> 2.8) + bigdecimal (>= 3.1, < 5) jwt (3.1.2) base64 kgio (2.11.4) language_server-protocol (3.17.0.5) libxml-ruby (5.0.5) + link_header (0.0.8) lint_roller (1.1.0) logger (1.7.0) macaddr (1.7.2) @@ -273,28 +312,33 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0924) + mime-types-data (3.2026.0113) mini_mime (1.1.5) - minitest (5.26.0) - minitest-bisect (1.7.0) - minitest-server (~> 1.0) - path_expander (~> 1.1) - minitest-hooks (1.5.2) + minitest (6.0.1) + prism (~> 1.5) + minitest-fail-fast (0.2.0) + minitest (>= 5.0, < 7) + minitest-hooks (1.5.3) minitest (> 5.3) - minitest-server (1.0.8) - drb (~> 2.0) - minitest (~> 5.16) + minitest-reporters (1.7.1) + ansi + builder + minitest (>= 5.0) + ruby-progressbar minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis - multi_json (1.17.0) + multi_json (1.19.1) + mustermann (3.0.4) + ruby2_keywords (~> 0.0.1) net-ftp (0.3.9) net-protocol time - net-http (0.7.0) - uri - net-http-persistent (2.9.4) - net-imap (0.5.12) + net-http (0.9.1) + uri (>= 0.11.1) + net-http-persistent (4.0.8) + connection_pool (>= 2.2.4, < 4) + net-imap (0.6.2) date net-protocol net-pop (0.1.2) @@ -309,60 +353,80 @@ GEM net-protocol net-ssh (7.3.0) netrc (0.11.0) - newrelic_rpm (9.19.0) - oj (3.16.12) + newrelic_rpm (10.0.0) + logger + oj (3.16.13) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) logger os (1.1.4) ostruct (0.6.3) + pandoc-ruby (2.1.10) parallel (1.27.0) parseconfig (1.1.2) - parser (3.3.8.0) + parser (3.3.10.1) ast (~> 2.4.1) racc - path_expander (1.1.3) pony (1.13.1) mail (>= 2.0) - prism (1.4.0) - pry (0.15.2) + prism (1.8.0) + pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (6.0.2) + reline (>= 0.6.0) + public_suffix (7.0.2) racc (1.8.1) - rack (1.6.13) + rack (3.2.4) rack-accept (0.4.5) rack (>= 0.4) - rack-attack (6.6.1) - rack (>= 1.0, < 3) - rack-cache (1.13.0) + rack-attack (6.8.0) + rack (>= 1.0, < 4) + rack-cache (1.17.0) rack (>= 0.4) - rack-cors (1.0.6) - rack (>= 1.6.0) - rack-mini-profiler (4.0.0) + rack-contrib (2.5.0) + rack (< 4) + rack-cors (3.0.0) + logger + rack (>= 3.0.14) + rack-mini-profiler (4.0.1) rack (>= 1.2.0) - rack-protection (1.5.5) - rack + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) rack-timeout (0.7.0) + rackup (2.3.1) + rack (>= 3) rainbow (3.1.1) raindrops (0.20.1) - rake (10.5.0) - rdf (1.0.8) - addressable (>= 2.2) - redcarpet (3.6.1) + rake (13.3.1) + rdf (3.3.1) + bcp47_spec (~> 0.2) + link_header (~> 0.0, >= 0.0.8) + rdf-rdfxml (3.3.0) + builder (~> 3.2, >= 3.2.4) + htmlentities (~> 4.3) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + rdf-vocab (3.3.3) + rdf (~> 3.3) + rdf-xsd (3.3.0) + rdf (~> 3.3) + rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.1) + redis-client (0.26.3) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) redis-store (>= 1.6, < 2) redis-store (1.11.0) redis (>= 4, < 6) - regexp_parser (2.10.0) + regexp_parser (2.11.3) + reline (0.6.3) + io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) rest-client (2.1.0) @@ -370,11 +434,11 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.4.1) + rexml (3.4.4) rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) - rubocop (1.78.0) + rubocop (1.82.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -382,17 +446,19 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.45.1, < 2.0) + rubocop-ast (>= 1.48.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.46.0) + rubocop-ast (1.49.0) parser (>= 3.3.7.2) - prism (~> 1.4) + prism (~> 1.7) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) + ruby2_keywords (0.0.5) rubyzip (3.2.2) rufus-scheduler (2.0.24) tzinfo (>= 0.3.22) + securerandom (0.4.1) signet (0.21.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) @@ -402,25 +468,19 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-cobertura (3.0.0) + simplecov-cobertura (3.1.0) rexml simplecov (~> 0.19) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) - sinatra (1.4.8) - rack (~> 1.5) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) - sinatra-advanced-routes (0.5.3) - sinatra (~> 1.0) - sinatra-contrib (1.4.7) - backports (>= 2.0) - multi_json - rack-protection - rack-test - sinatra (~> 1.4.0) - tilt (>= 1.3, < 3) - sshkit (1.24.0) + sinatra (4.2.1) + logger (>= 1.6.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.2.1) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) + sshkit (1.25.0) base64 logger net-scp (>= 1.1.2) @@ -428,17 +488,16 @@ GEM net-ssh (>= 2.8.0) ostruct systemu (2.6.5) - temple (0.10.3) - thread_safe (0.3.6) - tilt (2.6.1) - time (0.4.1) + temple (0.10.4) + tilt (2.7.0) + time (0.4.2) date - timeout (0.4.4) - tzinfo (1.2.11) - thread_safe (~> 0.1) - unicode-display_width (3.1.4) - unicode-emoji (~> 4.0, >= 4.0.4) - unicode-emoji (4.0.4) + timeout (0.6.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) unicorn (6.1.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -448,11 +507,11 @@ GEM uri (1.1.1) uuid (2.3.9) macaddr (~> 1.0) - webmock (3.19.1) + webmock (3.26.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.9.1) + webrick (1.9.2) PLATFORMS aarch64-linux @@ -471,7 +530,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - activesupport (~> 5) + activesupport bcrypt_pbkdf (>= 1.0, < 2.0) bigdecimal byebug (~> 12.0) @@ -484,46 +543,55 @@ DEPENDENCIES ed25519 (>= 1.2, < 2.0) ffi goo! + google-protobuf (= 3.25.3) + grpc (= 1.70.1) haml (~> 5.2.2) - json-schema (~> 2.0) - minitest (~> 5.0) - minitest-bisect - minitest-hooks (~> 1.5) + json-ld (~> 3.2.0) + json-schema + minitest + minitest-fail-fast + minitest-hooks + minitest-reporters minitest-stub_any_instance multi_json ncbo_annotator! ncbo_cron! ncbo_ontology_recommender! + net-ftp newrelic_rpm oj ontologies_linked_data! + pandoc-ruby + parallel parseconfig rack - rack-accept (~> 0.4) - rack-attack (~> 6.6.1) - rack-cache (~> 1.13.0) + rack-accept + rack-attack + rack-cache + rack-contrib rack-cors rack-mini-profiler rack-post-body-to-params! rack-test rack-timeout - rake (~> 10.0) - redcarpet + rackup + rake + rdf-raptor! redis - redis-rack-cache (~> 2.0) - redis-store (~> 1.10) + redis-rack-cache + redis-store + request_store rexml rubocop shotgun! simplecov simplecov-cobertura - sinatra (~> 1.0) - sinatra-advanced-routes - sinatra-contrib (~> 1.0) + sinatra + sinatra-contrib! sparql-client! unicorn unicorn-worker-killer - webmock (~> 3.19.1) + webmock webrick BUNDLED WITH diff --git a/Rakefile b/Rakefile index 87565be14..749a5baa2 100644 --- a/Rakefile +++ b/Rakefile @@ -4,29 +4,34 @@ task default: %w[test] Rake::TestTask.new do |t| t.libs = [] + t.warning = false t.test_files = FileList['test/**/test*.rb'] end Rake::TestTask.new do |t| t.libs = [] + t.warning = false t.name = "test:controllers" t.test_files = FileList['test/controllers/test*.rb'] end Rake::TestTask.new do |t| t.libs = [] + t.warning = false t.name = "test:models" t.test_files = FileList['test/models/test*.rb'] end Rake::TestTask.new do |t| t.libs = [] + t.warning = false t.name = "test:helpers" t.test_files = FileList['test/helpers/test*.rb'] end Rake::TestTask.new do |t| t.libs = [] + t.warning = false t.name = "test:lib" t.test_files = FileList['test/lib/test*.rb'] end diff --git a/app.rb b/app.rb index e09178bd0..53854e10f 100644 --- a/app.rb +++ b/app.rb @@ -1,10 +1,11 @@ +$VERBOSE = false + # sinatra-base require 'sinatra' # sinatra-contrib require 'sinatra/respond_with' require 'sinatra/namespace' -require 'sinatra/advanced_routes' require 'sinatra/multi_route' # Other gem dependencies @@ -24,7 +25,6 @@ require 'rack-timeout' require 'rack/cors' require_relative 'lib/rack/slow_requests' -require_relative 'lib/rack/cube_reporter' require_relative 'lib/rack/param_translator' require_relative 'lib/rack/slice_detection' require_relative 'lib/rack/request_lang' @@ -84,6 +84,9 @@ set :raise_errors, true set :dump_errors, false set :show_exceptions, false + # use Rack::DowncaseHeaders to ensure headers are downcased for rack > 3.0 compatibility + require_relative 'lib/rack/downcase_headers' + use Rack::DowncaseHeaders end # mini-profiler sets the etag header to nil, so don't use when caching is enabled diff --git a/config/deploy.rb b/config/deploy.rb index 2d7497be6..9c0b599ce 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -106,9 +106,8 @@ end end - after :publishing, :get_config - after :get_config, :restart - # after :deploy, :smoke_test + after :updating, :get_config + after :publishing, :restart after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do diff --git a/config/environments/config.rb.sample b/config/environments/config.rb.sample index e8667dc44..f153cfe16 100644 --- a/config/environments/config.rb.sample +++ b/config/environments/config.rb.sample @@ -19,8 +19,8 @@ REDIS_PORT = ENV.include?("REDIS_PORT") ? ENV["REDIS_PORT" REPORT_PATH = ENV.include?("REPORT_PATH") ? ENV["REPORT_PATH"] : "./test/ontologies_report.json" REPOSITORY_FOLDER = ENV.include?("REPOSITORY_FOLDER") ? ENV["REPOSITORY_FOLDER"] : "./test/data/ontology_files/repo" REST_URL_PREFIX = ENV.include?("REST_URL_PREFIX") ? ENV["REST_URL_PREFIX"] : "http://localhost:9393" -SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr/prop_search_core1" -SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr/term_search_core1" +SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr" +SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr" LinkedData.config do |config| config.goo_backend_name = GOO_BACKEND_NAME.to_s diff --git a/config/environments/test.rb b/config/environments/test.rb index 9eccf1d9b..61d5ef509 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -12,7 +12,7 @@ GOO_PATH_DATA = ENV.include?("GOO_PATH_DATA") ? ENV["GOO_PATH_DATA"] : "/data/" GOO_PATH_QUERY = ENV.include?("GOO_PATH_QUERY") ? ENV["GOO_PATH_QUERY"] : "/sparql/" GOO_PATH_UPDATE = ENV.include?("GOO_PATH_UPDATE") ? ENV["GOO_PATH_UPDATE"] : "/update/" -GOO_PORT = ENV.include?("GOO_PORT") ? ENV["GOO_PORT"] : 8080 +GOO_PORT = ENV.include?("GOO_PORT") ? ENV["GOO_PORT"] : 9000 MGREP_DICTIONARY_FILE = ENV.include?("MGREP_DICTIONARY_FILE") ? ENV["MGREP_DICTIONARY_FILE"] : "./test/data/dictionary.txt" MGREP_HOST = ENV.include?("MGREP_HOST") ? ENV["MGREP_HOST"] : "localhost" @@ -28,8 +28,8 @@ REDIS_PORT = ENV.include?("REDIS_PORT") ? ENV["REDIS_PORT"] : 6379 REPORT_PATH = ENV.include?("REPORT_PATH") ? ENV["REPORT_PATH"] : "./test/ontologies_report.json" REPOSITORY_FOLDER = ENV.include?("REPOSITORY_FOLDER") ? ENV["REPOSITORY_FOLDER"] : "./test/data/ontology_files/repo" -SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr/prop_search_core1" -SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr/term_search_core1" +SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr" +SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr" LinkedData.config do |config| config.goo_backend_name = GOO_BACKEND_NAME.to_s diff --git a/config/logging.rb b/config/logging.rb index e37ba4aa3..03f2382ba 100644 --- a/config/logging.rb +++ b/config/logging.rb @@ -1,23 +1,9 @@ require 'logger' -class CustomLogger < Logger - alias write << - def flush - ((self.instance_variable_get :@logdev).instance_variable_get :@dev).flush - end -end - -# Setup global logging -require 'rack/logger' -# if [:development, :console, :test].include?(settings.environment) -if [:development, :console].include?(settings.environment) - LOGGER = CustomLogger.new(STDOUT) - LOGGER.level = Logger::DEBUG -else - Dir.mkdir('log') unless File.exist?('log') - log = File.new("log/#{settings.environment}.log", "a+") - log.sync = true - LOGGER = CustomLogger.new(log) - LOGGER.level = Logger::INFO - use Rack::CommonLogger, log -end +configure do + log_file = File.new("log/#{settings.environment}.log", 'a+') + log_file.sync = true + LOGGER = Logger.new(log_file) + LOGGER.level = settings.development? ? Logger::DEBUG : Logger::INFO + set :logger, LOGGER +end \ No newline at end of file diff --git a/config/solr/property_search/enumsconfig.xml b/config/solr/property_search/enumsconfig.xml deleted file mode 100644 index 72e7b7d31..000000000 --- a/config/solr/property_search/enumsconfig.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - ONTOLOGY - VALUE_SET_COLLECTION - - - ANNOTATION - DATATYPE - OBJECT - - \ No newline at end of file diff --git a/config/solr/property_search/mapping-ISOLatin1Accent.txt b/config/solr/property_search/mapping-ISOLatin1Accent.txt deleted file mode 100644 index ede774258..000000000 --- a/config/solr/property_search/mapping-ISOLatin1Accent.txt +++ /dev/null @@ -1,246 +0,0 @@ -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Syntax: -# "source" => "target" -# "source".length() > 0 (source cannot be empty.) -# "target".length() >= 0 (target can be empty.) - -# example: -# "À" => "A" -# "\u00C0" => "A" -# "\u00C0" => "\u0041" -# "ß" => "ss" -# "\t" => " " -# "\n" => "" - -# À => A -"\u00C0" => "A" - -# Á => A -"\u00C1" => "A" - -#  => A -"\u00C2" => "A" - -# à => A -"\u00C3" => "A" - -# Ä => A -"\u00C4" => "A" - -# Å => A -"\u00C5" => "A" - -# Æ => AE -"\u00C6" => "AE" - -# Ç => C -"\u00C7" => "C" - -# È => E -"\u00C8" => "E" - -# É => E -"\u00C9" => "E" - -# Ê => E -"\u00CA" => "E" - -# Ë => E -"\u00CB" => "E" - -# Ì => I -"\u00CC" => "I" - -# Í => I -"\u00CD" => "I" - -# Î => I -"\u00CE" => "I" - -# Ï => I -"\u00CF" => "I" - -# IJ => IJ -"\u0132" => "IJ" - -# Ð => D -"\u00D0" => "D" - -# Ñ => N -"\u00D1" => "N" - -# Ò => O -"\u00D2" => "O" - -# Ó => O -"\u00D3" => "O" - -# Ô => O -"\u00D4" => "O" - -# Õ => O -"\u00D5" => "O" - -# Ö => O -"\u00D6" => "O" - -# Ø => O -"\u00D8" => "O" - -# Œ => OE -"\u0152" => "OE" - -# Þ -"\u00DE" => "TH" - -# Ù => U -"\u00D9" => "U" - -# Ú => U -"\u00DA" => "U" - -# Û => U -"\u00DB" => "U" - -# Ü => U -"\u00DC" => "U" - -# Ý => Y -"\u00DD" => "Y" - -# Ÿ => Y -"\u0178" => "Y" - -# à => a -"\u00E0" => "a" - -# á => a -"\u00E1" => "a" - -# â => a -"\u00E2" => "a" - -# ã => a -"\u00E3" => "a" - -# ä => a -"\u00E4" => "a" - -# å => a -"\u00E5" => "a" - -# æ => ae -"\u00E6" => "ae" - -# ç => c -"\u00E7" => "c" - -# è => e -"\u00E8" => "e" - -# é => e -"\u00E9" => "e" - -# ê => e -"\u00EA" => "e" - -# ë => e -"\u00EB" => "e" - -# ì => i -"\u00EC" => "i" - -# í => i -"\u00ED" => "i" - -# î => i -"\u00EE" => "i" - -# ï => i -"\u00EF" => "i" - -# ij => ij -"\u0133" => "ij" - -# ð => d -"\u00F0" => "d" - -# ñ => n -"\u00F1" => "n" - -# ò => o -"\u00F2" => "o" - -# ó => o -"\u00F3" => "o" - -# ô => o -"\u00F4" => "o" - -# õ => o -"\u00F5" => "o" - -# ö => o -"\u00F6" => "o" - -# ø => o -"\u00F8" => "o" - -# œ => oe -"\u0153" => "oe" - -# ß => ss -"\u00DF" => "ss" - -# þ => th -"\u00FE" => "th" - -# ù => u -"\u00F9" => "u" - -# ú => u -"\u00FA" => "u" - -# û => u -"\u00FB" => "u" - -# ü => u -"\u00FC" => "u" - -# ý => y -"\u00FD" => "y" - -# ÿ => y -"\u00FF" => "y" - -# ff => ff -"\uFB00" => "ff" - -# fi => fi -"\uFB01" => "fi" - -# fl => fl -"\uFB02" => "fl" - -# ffi => ffi -"\uFB03" => "ffi" - -# ffl => ffl -"\uFB04" => "ffl" - -# ſt => ft -"\uFB05" => "ft" - -# st => st -"\uFB06" => "st" diff --git a/config/solr/property_search/schema.xml b/config/solr/property_search/schema.xml deleted file mode 100644 index 20824ea65..000000000 --- a/config/solr/property_search/schema.xml +++ /dev/null @@ -1,1179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - id - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/config/solr/property_search/solrconfig.xml b/config/solr/property_search/solrconfig.xml deleted file mode 100644 index 771a0f322..000000000 --- a/config/solr/property_search/solrconfig.xml +++ /dev/null @@ -1,1299 +0,0 @@ - - - - - - - - - 8.8.2 - - - - - - - - - - - ${solr.data.dir:} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${solr.lock.type:native} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${solr.ulog.dir:} - ${solr.ulog.numVersionBuckets:65536} - - - - - ${solr.autoCommit.maxTime:15000} - false - - - - - - ${solr.autoSoftCommit.maxTime:-1} - - - - - - - - - - - - - - ${solr.max.booleanClauses:500000} - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - 20 - - - 200 - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - explicit - 10 - - - - - - - - - - - - - - - - explicit - json - true - - - - - - _text_ - - - - - - - - - text_general - - - - - - default - _text_ - solr.DirectSolrSpellChecker - - internal - - 0.5 - - 2 - - 1 - - 5 - - 4 - - 0.01 - - - - - - - - - - - - default - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - - - true - false - - - terms - - - - - - - - - - - 100 - - - - - - - - 70 - - 0.5 - - [-\w ,/\n\"']{20,200} - - - - - - - ]]> - ]]> - - - - - - - - - - - - - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - - WORD - - - en - US - - - - - - - - - - - - [^\w-\.] - _ - - - - - - - yyyy-MM-dd['T'[HH:mm[:ss[.SSS]][z - yyyy-MM-dd['T'[HH:mm[:ss[,SSS]][z - yyyy-MM-dd HH:mm[:ss[.SSS]][z - yyyy-MM-dd HH:mm[:ss[,SSS]][z - [EEE, ]dd MMM yyyy HH:mm[:ss] z - EEEE, dd-MMM-yy HH:mm:ss z - EEE MMM ppd HH:mm:ss [z ]yyyy - - - - - java.lang.String - text_general - - *_str - 256 - - - true - - - java.lang.Boolean - booleans - - - java.util.Date - pdates - - - java.lang.Long - java.lang.Integer - plongs - - - java.lang.Number - pdoubles - - - - - - - - - - - - - - - - - - - - text/plain; charset=UTF-8 - - - - - - - - - - - - - - diff --git a/config/solr/solr.xml b/config/solr/solr.xml deleted file mode 100644 index d9d089e4d..000000000 --- a/config/solr/solr.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - ${solr.max.booleanClauses:500000} - ${solr.sharedLib:} - ${solr.allowPaths:} - - - - ${host:} - ${solr.port.advertise:0} - ${hostContext:solr} - - ${genericCoreNodeNames:true} - - ${zkClientTimeout:30000} - ${distribUpdateSoTimeout:600000} - ${distribUpdateConnTimeout:60000} - ${zkCredentialsProvider:org.apache.solr.common.cloud.DefaultZkCredentialsProvider} - ${zkACLProvider:org.apache.solr.common.cloud.DefaultZkACLProvider} - - - - - ${socketTimeout:600000} - ${connTimeout:60000} - ${solr.shardsWhitelist:} - - - - - diff --git a/config/solr/term_search/enumsconfig.xml b/config/solr/term_search/enumsconfig.xml deleted file mode 100644 index 72e7b7d31..000000000 --- a/config/solr/term_search/enumsconfig.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - ONTOLOGY - VALUE_SET_COLLECTION - - - ANNOTATION - DATATYPE - OBJECT - - \ No newline at end of file diff --git a/config/solr/term_search/mapping-ISOLatin1Accent.txt b/config/solr/term_search/mapping-ISOLatin1Accent.txt deleted file mode 100644 index ede774258..000000000 --- a/config/solr/term_search/mapping-ISOLatin1Accent.txt +++ /dev/null @@ -1,246 +0,0 @@ -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Syntax: -# "source" => "target" -# "source".length() > 0 (source cannot be empty.) -# "target".length() >= 0 (target can be empty.) - -# example: -# "À" => "A" -# "\u00C0" => "A" -# "\u00C0" => "\u0041" -# "ß" => "ss" -# "\t" => " " -# "\n" => "" - -# À => A -"\u00C0" => "A" - -# Á => A -"\u00C1" => "A" - -#  => A -"\u00C2" => "A" - -# à => A -"\u00C3" => "A" - -# Ä => A -"\u00C4" => "A" - -# Å => A -"\u00C5" => "A" - -# Æ => AE -"\u00C6" => "AE" - -# Ç => C -"\u00C7" => "C" - -# È => E -"\u00C8" => "E" - -# É => E -"\u00C9" => "E" - -# Ê => E -"\u00CA" => "E" - -# Ë => E -"\u00CB" => "E" - -# Ì => I -"\u00CC" => "I" - -# Í => I -"\u00CD" => "I" - -# Î => I -"\u00CE" => "I" - -# Ï => I -"\u00CF" => "I" - -# IJ => IJ -"\u0132" => "IJ" - -# Ð => D -"\u00D0" => "D" - -# Ñ => N -"\u00D1" => "N" - -# Ò => O -"\u00D2" => "O" - -# Ó => O -"\u00D3" => "O" - -# Ô => O -"\u00D4" => "O" - -# Õ => O -"\u00D5" => "O" - -# Ö => O -"\u00D6" => "O" - -# Ø => O -"\u00D8" => "O" - -# Œ => OE -"\u0152" => "OE" - -# Þ -"\u00DE" => "TH" - -# Ù => U -"\u00D9" => "U" - -# Ú => U -"\u00DA" => "U" - -# Û => U -"\u00DB" => "U" - -# Ü => U -"\u00DC" => "U" - -# Ý => Y -"\u00DD" => "Y" - -# Ÿ => Y -"\u0178" => "Y" - -# à => a -"\u00E0" => "a" - -# á => a -"\u00E1" => "a" - -# â => a -"\u00E2" => "a" - -# ã => a -"\u00E3" => "a" - -# ä => a -"\u00E4" => "a" - -# å => a -"\u00E5" => "a" - -# æ => ae -"\u00E6" => "ae" - -# ç => c -"\u00E7" => "c" - -# è => e -"\u00E8" => "e" - -# é => e -"\u00E9" => "e" - -# ê => e -"\u00EA" => "e" - -# ë => e -"\u00EB" => "e" - -# ì => i -"\u00EC" => "i" - -# í => i -"\u00ED" => "i" - -# î => i -"\u00EE" => "i" - -# ï => i -"\u00EF" => "i" - -# ij => ij -"\u0133" => "ij" - -# ð => d -"\u00F0" => "d" - -# ñ => n -"\u00F1" => "n" - -# ò => o -"\u00F2" => "o" - -# ó => o -"\u00F3" => "o" - -# ô => o -"\u00F4" => "o" - -# õ => o -"\u00F5" => "o" - -# ö => o -"\u00F6" => "o" - -# ø => o -"\u00F8" => "o" - -# œ => oe -"\u0153" => "oe" - -# ß => ss -"\u00DF" => "ss" - -# þ => th -"\u00FE" => "th" - -# ù => u -"\u00F9" => "u" - -# ú => u -"\u00FA" => "u" - -# û => u -"\u00FB" => "u" - -# ü => u -"\u00FC" => "u" - -# ý => y -"\u00FD" => "y" - -# ÿ => y -"\u00FF" => "y" - -# ff => ff -"\uFB00" => "ff" - -# fi => fi -"\uFB01" => "fi" - -# fl => fl -"\uFB02" => "fl" - -# ffi => ffi -"\uFB03" => "ffi" - -# ffl => ffl -"\uFB04" => "ffl" - -# ſt => ft -"\uFB05" => "ft" - -# st => st -"\uFB06" => "st" diff --git a/config/solr/term_search/schema.xml b/config/solr/term_search/schema.xml deleted file mode 100644 index 73c75b31f..000000000 --- a/config/solr/term_search/schema.xml +++ /dev/null @@ -1,1224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - id - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/config/solr/term_search/solrconfig.xml b/config/solr/term_search/solrconfig.xml deleted file mode 100644 index 771a0f322..000000000 --- a/config/solr/term_search/solrconfig.xml +++ /dev/null @@ -1,1299 +0,0 @@ - - - - - - - - - 8.8.2 - - - - - - - - - - - ${solr.data.dir:} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${solr.lock.type:native} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${solr.ulog.dir:} - ${solr.ulog.numVersionBuckets:65536} - - - - - ${solr.autoCommit.maxTime:15000} - false - - - - - - ${solr.autoSoftCommit.maxTime:-1} - - - - - - - - - - - - - - ${solr.max.booleanClauses:500000} - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - 20 - - - 200 - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - explicit - 10 - - - - - - - - - - - - - - - - explicit - json - true - - - - - - _text_ - - - - - - - - - text_general - - - - - - default - _text_ - solr.DirectSolrSpellChecker - - internal - - 0.5 - - 2 - - 1 - - 5 - - 4 - - 0.01 - - - - - - - - - - - - default - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - - - true - false - - - terms - - - - - - - - - - - 100 - - - - - - - - 70 - - 0.5 - - [-\w ,/\n\"']{20,200} - - - - - - - ]]> - ]]> - - - - - - - - - - - - - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - - WORD - - - en - US - - - - - - - - - - - - [^\w-\.] - _ - - - - - - - yyyy-MM-dd['T'[HH:mm[:ss[.SSS]][z - yyyy-MM-dd['T'[HH:mm[:ss[,SSS]][z - yyyy-MM-dd HH:mm[:ss[.SSS]][z - yyyy-MM-dd HH:mm[:ss[,SSS]][z - [EEE, ]dd MMM yyyy HH:mm[:ss] z - EEEE, dd-MMM-yy HH:mm:ss z - EEE MMM ppd HH:mm:ss [z ]yyyy - - - - - java.lang.String - text_general - - *_str - 256 - - - true - - - java.lang.Boolean - booleans - - - java.util.Date - pdates - - - java.lang.Long - java.lang.Integer - plongs - - - java.lang.Number - pdoubles - - - - - - - - - - - - - - - - - - - - text/plain; charset=UTF-8 - - - - - - - - - - - - - - diff --git a/controllers/home_controller.rb b/controllers/home_controller.rb index fc6d03947..654b50e02 100644 --- a/controllers/home_controller.rb +++ b/controllers/home_controller.rb @@ -1,5 +1,4 @@ require 'haml' -require 'redcarpet' class HomeController < ApplicationController diff --git a/controllers/notes_controller.rb b/controllers/notes_controller.rb index 804f4cf6a..ab7742f21 100644 --- a/controllers/notes_controller.rb +++ b/controllers/notes_controller.rb @@ -1,7 +1,7 @@ class NotesController < ApplicationController ## # Ontology notes - get "/ontologies/:ontology/notes?:include_threads?" do + get '/ontologies/:ontology/notes' do ont = Ontology.find(params["ontology"]).include(:acronym).first error 404, "You must provide a valid id to retrieve notes for an ontology" if ont.nil? check_last_modified_segment(LinkedData::Models::Note, [ont.acronym]) @@ -13,7 +13,7 @@ class NotesController < ApplicationController ## # Class notes - get "/ontologies/:ontology/classes/:cls/notes?:include_threads?" do + get "/ontologies/:ontology/classes/:cls/notes" do ont = Ontology.find(params["ontology"]).include(:submissions, :acronym).first error 404, "You must provide a valid id to retrieve notes for an ontology" if ont.nil? check_last_modified_segment(LinkedData::Models::Note, [ont.acronym]) @@ -27,7 +27,7 @@ class NotesController < ApplicationController namespace "/notes" do # Display all notes - get "?:include_threads?" do + get '' do check_last_modified_collection(LinkedData::Models::Note) notes = LinkedData::Models::Note.where.include(LinkedData::Models::Note.goo_attrs_to_load(includes_param)).to_a recurse_replies(notes) if params["include_threads"] @@ -35,7 +35,7 @@ class NotesController < ApplicationController end # Display a single note - get '/:noteid?:include_threads?' do + get '/:noteid' do noteid = params["noteid"] note = LinkedData::Models::Note.find(noteid).include(relatedOntology: [:acronym]).first error 404, "Note #{noteid} not found" if note.nil? @@ -94,10 +94,8 @@ class NotesController < ApplicationController def note_from_params note_params = params.dup - note_params.delete("creator") proposal_params = clean_notes_hash(note_params.delete("proposal")) note = instance_from_params(LinkedData::Models::Note, clean_notes_hash(note_params)) - note.creator = current_user if proposal_params proposal = instance_from_params(LinkedData::Models::Notes::Proposal, proposal_params) @@ -123,4 +121,4 @@ def clean_notes_hash(hash) hash end end -end +end \ No newline at end of file diff --git a/controllers/properties_search_controller.rb b/controllers/properties_search_controller.rb index 29d6b7726..540aa0150 100644 --- a/controllers/properties_search_controller.rb +++ b/controllers/properties_search_controller.rb @@ -22,7 +22,7 @@ def process_search(params=nil) # puts "Properties query: #{query}, params: #{params}" set_page_params(params) docs = Array.new - resp = LinkedData::Models::Class.search(query, params, :property) + resp = LinkedData::Models::OntologyProperty.search(query, params) total_found = resp["response"]["numFound"] add_matched_fields(resp, Sinatra::Helpers::SearchHelper::MATCH_TYPE_LABEL) ontology_rank = LinkedData::Models::Ontology.rank @@ -52,4 +52,4 @@ def process_search(params=nil) end end -end +end \ No newline at end of file diff --git a/controllers/replies_controller.rb b/controllers/replies_controller.rb index 081238a17..1f63b54a7 100644 --- a/controllers/replies_controller.rb +++ b/controllers/replies_controller.rb @@ -12,7 +12,7 @@ class RepliesController < ApplicationController namespace "/replies" do # Display all replies - get "?:include_threads?" do + get '' do check_last_modified_collection(LinkedData::Models::Notes::Reply) replies = LinkedData::Models::Notes::Reply.where.include(LinkedData::Models::Notes::Reply.goo_attrs_to_load(includes_param)).to_a reply replies diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index e97366916..c2f3da7b2 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -188,9 +188,19 @@ def halt(*response) status = obj obj = nil end - status, obj = response.first, response.last if response.length == 2 - status, headers, obj = response.first, response[1], response.last if response.length == 3 - if obj.is_a?(Rack::File) # Avoid the serializer when returning files + + if response.length == 2 + status = response.first + obj = response.last + end + + if response.length == 3 + status = response.first + headers = response[1] + obj = response.last + end + + if obj.is_a?(Rack::Files) || obj.is_a?(Rack::Files::Iterator) # Avoid the serializer when returning files super(response) else super(LinkedData::Serializer.build_response(@env, status: status, headers: headers, ld_object: obj)) diff --git a/init.rb b/init.rb index 44a1eef52..ff7ee7c09 100644 --- a/init.rb +++ b/init.rb @@ -1,34 +1,30 @@ -# Recursively require files from directories and their sub-directories +# Recursively require files from directories def require_dir(dir) - Dir.glob("#{dir}/*.rb").each {|f| require_relative f } - Dir.glob("#{dir}/*/").each {|d| require_dir(d.gsub(/\/+$/, '')) } + Dir.glob("#{dir}/**/*.rb").sort.each { |f| require_relative f } end -# Require controller base files -require_relative "controllers/application_controller" +# Require core files +require_relative 'controllers/application_controller' +require_dir('lib') +require_dir('helpers') +require_dir('models') +require_dir('controllers') -# Require known directories -require_dir("lib") -require_dir("helpers") -require_dir("models") -require_dir("controllers") +# Add optional trailing slash to routes +Sinatra.register do + def self.registered(app) + app.routes.each do |verb, routes| + routes.each do |route| + pattern = route[0] + next if pattern.to_s.end_with?('/') -## -# Look for routes without an optional trailing slash or existing trailing slash -# and add the optional trailing slash so both /ontologies/ and /ontologies works -def rewrite_routes_trailing_slash - trailing_slash = Regexp.new(/.*\/\?\\z/) - no_trailing_slash = Regexp.new(/(.*)\\z\//) - Sinatra::Application.routes.each do |method, routes| - routes.each do |r| - route_regexp_str = r[0].inspect - if trailing_slash.match(route_regexp_str) - next - else - new_route = route_regexp_str.gsub(no_trailing_slash, "\\1\\/?\\z/") - r[0] = eval(new_route) + http_verb = verb.to_s.downcase + app.public_send(http_verb, "#{pattern}/") do + pass unless request.path_info.end_with?('/') + redirect_path = request.path_info.chomp('/') + redirect redirect_path, 301 + end end end end -end -rewrite_routes_trailing_slash() \ No newline at end of file +end \ No newline at end of file diff --git a/test/controllers/test_properties_search_controller.rb b/test/controllers/test_properties_search_controller.rb index 2a8cadd0a..7d2d961e5 100644 --- a/test/controllers/test_properties_search_controller.rb +++ b/test/controllers/test_properties_search_controller.rb @@ -30,8 +30,8 @@ def before_suite def after_suite LinkedData::SampleData::Ontology.delete_ontologies_and_submissions - LinkedData::Models::Ontology.indexClear(:property) - LinkedData::Models::Ontology.indexCommit(nil, :property) + LinkedData::Models::OntologyProperty.indexClear + LinkedData::Models::OntologyProperty.indexCommit end def test_property_search diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index 1e98a84a5..c8234c078 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -4,6 +4,10 @@ class TestSearchController < TestCase def before_suite self.backend_4s_delete + LinkedData::Models::Ontology.indexClear + LinkedData::Models::Class.indexClear + LinkedData::Models::OntologyProperty.indexClear + count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ process_submission: true, acronym: "BROSEARCHTEST", diff --git a/test/helpers/test_slices_helper.rb b/test/helpers/test_slices_helper.rb index 9639c6b17..bfe4b618b 100644 --- a/test/helpers/test_slices_helper.rb +++ b/test/helpers/test_slices_helper.rb @@ -4,6 +4,7 @@ class TestSlicesHelper < TestCaseHelpers def before_suite self.backend_4s_delete + LinkedData::Models::Class.indexClear @@orig_slices_setting = LinkedData.settings.enable_slices LinkedData.settings.enable_slices = true diff --git a/test/test_case.rb b/test/test_case.rb index 5e8265b84..f68c32b77 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -76,12 +76,14 @@ def count_pattern(pattern) def backend_4s_delete if count_pattern("?s ?p ?o") < 400000 - LinkedData::Models::Ontology.where.include(:acronym).each do |o| - query = "submissionAcronym:#{o.acronym}" - LinkedData::Models::Ontology.unindexByQuery(query) + puts 'clear backend & index' + raise StandardError, 'Too many triples in KB, does not seem right to run tests' unless count_pattern('?s ?p ?o') < 400000 + + graphs = Goo.sparql_query_client.query("SELECT DISTINCT ?g WHERE { GRAPH ?g { ?s ?p ?o . } }") + graphs.each_solution do |sol| + Goo.sparql_data_client.delete_graph(sol[:g]) end - LinkedData::Models::Ontology.indexCommit() - Goo.sparql_update_client.update("DELETE {?s ?p ?o } WHERE { ?s ?p ?o }") + LinkedData::Models::SubmissionStatus.init_enum LinkedData::Models::OntologyType.init_enum LinkedData::Models::OntologyFormat.init_enum @@ -110,7 +112,27 @@ def after_all after_suite super end + + def _run_suite(suite, type) + begin + backend_4s_delete + LinkedData::Models::Ontology.indexClear + LinkedData::Models::Class.indexClear + LinkedData::Models::OntologyProperty.indexClear + suite.before_suite if suite.respond_to?(:before_suite) + super(suite, type) + rescue Exception => e + puts e.message + puts e.backtrace.join("\n\t") + puts "Traced from:" + raise e + ensure + backend_4s_delete + suite.after_suite if suite.respond_to?(:after_suite) + end + end end + # All tests should inherit from this class. # Use 'rake test' from the command line to run tests. # See http://www.sinatrarb.com/testing.html for testing information From c8919ecb326911a426bc06c41e4d1c948beabd6b Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 22 Jan 2026 22:48:53 -0800 Subject: [PATCH 031/173] initial commit, work-in-progress: sinatra 4.2.1 compatibiity --- .../test_search_models_controller.rb | 423 ++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 test/controllers/test_search_models_controller.rb diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb new file mode 100644 index 000000000..ea741ee32 --- /dev/null +++ b/test/controllers/test_search_models_controller.rb @@ -0,0 +1,423 @@ +require_relative '../test_case' + +class TestSearchModelsController < TestCase + + def after_suite + LinkedData::SampleData::Ontology.delete_ontologies_and_submissions + LinkedData::Models::Ontology.indexClear + LinkedData::Models::Class.indexClear + LinkedData::Models::OntologyProperty.indexClear + Goo.init_search_connection(:ontology_data) + end + + def setup + after_suite + end + + def test_show_all_collection + get '/admin/search/collections' + assert last_response.ok? + res = MultiJson.load(last_response.body) + array = %w[agents_metadata ontology_data ontology_metadata prop_search_core1 term_search_core1] + assert_equal res["collections"].sort , array.sort + end + + def test_collection_schema + get '/admin/search/collections' + assert last_response.ok? + res = MultiJson.load(last_response.body) + collection = res["collections"].first + refute_nil collection + get "/admin/search/collections/#{collection}/schema" + assert last_response.ok? + res = MultiJson.load(last_response.body) + fields = res["fields"].map { |x| x["name"] } + assert_includes fields, 'id' + assert_includes fields, 'resource_id' + assert_includes fields, 'resource_model' + end + + def test_collection_search + + count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + collection = 'ontology_metadata' + post "/admin/search/collections/#{collection}/search", {q: ""} + + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal 2, res['response']['numFound'] + end + + def test_search_security + count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) + + + subs = LinkedData::Models::OntologySubmission.all + subs.each do |s| + s.bring_remaining + s.index_all(Logger.new($stdout)) + end + + + allowed_user = User.new({ + username: "allowed", + email: "test1@example.org", + password: "12345" + }) + allowed_user.save + + blocked_user = User.new({ + username: "blocked", + email: "test2@example.org", + password: "12345" + }) + blocked_user.save + + bro = bro.first + bro.bring_remaining + bro.acl = [allowed_user] + bro.viewingRestriction = "private" + bro.save + + self.class.enable_security + get "/search/ontologies?query=#{bro.acronym}&apikey=#{blocked_user.apikey}" + response = MultiJson.load(last_response.body)["collection"] + assert_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} + + get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{blocked_user.apikey}" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal 0, res['totalCount'] + + get "/search/ontologies?query=#{bro.acronym}&apikey=#{allowed_user.apikey}" + response = MultiJson.load(last_response.body)["collection"] + refute_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} + + get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{allowed_user.apikey}" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal 1, res['totalCount'] + + self.class.reset_security(false) + end + + def test_ontology_metadata_search + count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) + + # Search ACRONYM + ## full word + get '/search/ontologies?query=BROSEARCHTEST-0' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + + ### start + get '/search/ontologies?query=BROSEARCHTEST' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + + ## part of the word + get '/search/ontologies?query=BRO' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + + + # Search name + ## full word + ### start + get '/search/ontologies?query=MCCL Search' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'MCCLSEARCHTEST-0', response.first['ontology_acronym_text'] + ###in the middle + get '/search/ontologies?query=Search Test' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + ## part of the word + ### start + get '/search/ontologies?query=MCCL Sea' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'MCCLSEARCHTEST-0', response.first['ontology_acronym_text'] + ### in the middle + get '/search/ontologies?query=Sea' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + + + ## full text + get '/search/ontologies?query=MCCL Search Test' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 'MCCLSEARCHTEST-0', response.first['ontology_acronym_text'] + + + # Search description + ## full word + ### start + get '/search/ontologies?query=Description' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + + ### in the middle + get '/search/ontologies?query=1' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + + ## part of the word + ### start + get '/search/ontologies?query=Desc' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + + ### full text + get '/search/ontologies?query=Description 1' + response = MultiJson.load(last_response.body)["collection"] + assert_equal 2, response.size + assert_equal 'BROSEARCHTEST-0', response.first['ontology_acronym_text'] + assert_equal 'MCCLSEARCHTEST-0', response.last['ontology_acronym_text'] + end + + def test_ontology_metadata_filters + num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: 10, submission_count: 1) + + + group1 = LinkedData::Models::Group.find('group-1').first || LinkedData::Models::Group.new(acronym: 'group-1', name: "Test Group 1").save + group2 = LinkedData::Models::Group.find('group-2').first || LinkedData::Models::Group.new(acronym: 'group-2', name: "Test Group 2").save + category1 = LinkedData::Models::Category.find('category-1').first || LinkedData::Models::Category.new(acronym: 'category-1', name: "Test Category 1").save + category2 = LinkedData::Models::Category.find('category-2').first || LinkedData::Models::Category.new(acronym: 'category-2', name: "Test Category 2").save + + ontologies1 = ontologies[0..5].each do |o| + o.bring_remaining + o.group = [group1] + o.hasDomain = [category1] + o.save + end + + ontologies2 = ontologies[6..8].each do |o| + o.bring_remaining + o.group = [group2] + o.hasDomain = [category2] + o.save + end + + + # test filter by group and category + get "/search/ontologies?page=1&pagesize=100&groups=#{group1.acronym}" + assert last_response.ok? + assert_equal ontologies1.size, MultiJson.load(last_response.body)["collection"].length + get "/search/ontologies?page=1&pagesize=100&groups=#{group2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)["collection"].length + + + get "/search/ontologies?page=1&pagesize=100&groups=#{group1.acronym},#{group2.acronym}" + assert last_response.ok? + assert_equal ontologies1.size + ontologies2.size, MultiJson.load(last_response.body)["collection"].length + + get "/search/ontologies?page=1&pagesize=100&hasDomain=#{category1.acronym}" + assert last_response.ok? + assert_equal ontologies1.size, MultiJson.load(last_response.body)["collection"].length + + get "/search/ontologies?page=1&pagesize=100&hasDomain=#{category2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)["collection"].length + + get "/search/ontologies?page=1&pagesize=100&hasDomain=#{category2.acronym},#{category1.acronym}" + assert last_response.ok? + assert_equal ontologies1.size + ontologies2.size, MultiJson.load(last_response.body)["collection"].length + + get "/search/ontologies?page=1&pagesize=100&hasDomain=#{category2.acronym}&groups=#{group1.acronym}" + assert last_response.ok? + assert_equal 0, MultiJson.load(last_response.body)["collection"].length + get "/search/ontologies?page=1&pagesize=100&hasDomain=#{category2.acronym}&groups=#{group2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)["collection"].length + + + + ontologies3 = ontologies[9] + ontologies3.bring_remaining + ontologies3.group = [group1, group2] + ontologies3.hasDomain = [category1, category2] + ontologies3.name = "name search test" + ontologies3.save + + ontologies.first.name = "sort by test" + ontologies.first.save + sub = ontologies.first.latest_submission(status: :any).bring_remaining + sub.status = 'retired' + sub.description = "234" + sub.creationDate = DateTime.yesterday.to_datetime + sub.hasOntologyLanguage = LinkedData::Models::OntologyFormat.find('SKOS').first + sub.save + + #test search with sort + get "/search/ontologies?page=1&pagesize=100&q=tes&sort=ontology_name_sort asc" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + + refute_empty submissions["collection"] + assert_equal ontologies.map{|x| x.bring(:name).name}.sort, submissions["collection"].map{|x| x["ontology_name_text"]} + + get "/search/ontologies?page=1&pagesize=100&q=tes&sort=creationDate_dt desc" + + + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions["collection"] + assert_equal ontologies.map{|x| x.latest_submission(status: :any).bring(:creationDate).creationDate.to_s.split('T').first}.sort.reverse, + submissions["collection"].map{|x| x["creationDate_dt"].split('T').first} + + # test search with format + get "/search/ontologies?page=1&pagesize=100&q=tes&hasOntologyLanguage=SKOS" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + + refute_empty submissions["collection"] + assert_equal 1, submissions["collection"].size + + + + get "/search/ontologies?page=1&pagesize=100&q=tes&hasOntologyLanguage=OWL" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions["collection"] + assert_equal ontologies.size-1 , submissions["collection"].size + + + # test ontology filter with submission filter attributes + get "/search/ontologies?page=1&pagesize=100&q=tes&groups=group-2&hasDomain=category-2&hasOntologyLanguage=OWL" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions["collection"] + assert_equal ontologies2.size + 1 , submissions["collection"].size + + + + # test ontology filter with status + + get "/search/ontologies?page=1&pagesize=100&status=retired" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions["collection"] + assert_equal 1 , submissions["collection"].size + + get "/search/ontologies?page=1&pagesize=100&status=alpha,beta,production" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions["collection"] + assert_equal ontologies.size - 1 , submissions["collection"].size + + get "/search/ontologies?page=1&pagesize=100&q=234" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal "http://data.bioontology.org/ontologies/TEST-ONT-0/submissions/1" , submissions["collection"].first["id"] + end + + def test_search_data + skip "Test is not consistent, need to be fixed to work all the time" + count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) + + + subs = LinkedData::Models::OntologySubmission.all + count = [] + subs.each do |s| + count << Goo.sparql_query_client.query("SELECT (COUNT( DISTINCT ?id) as ?c) FROM <#{s.id}> WHERE {?id ?p ?v}") + .first[:c] + .to_i + end + + # TO-DO: Fix this test as it's not consistent + # get "/search/ontologies/content?q=*" + # assert last_response.ok? + # res = MultiJson.load(last_response.body) + # assert_equal count.sum, res['totalCount'] + + + get "/search/ontologies/content?q=*&ontologies=MCCLSEARCHTEST-0,BROSEARCHTEST-0" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal count.sum, res['totalCount'] + + get "/search/ontologies/content?q=*&ontologies=BROSEARCHTEST-0" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_includes count, res['totalCount'] + + get "/search/ontologies/content?q=*&ontologies=MCCLSEARCHTEST-0" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_includes count, res['totalCount'] + + end +end \ No newline at end of file From 9937e86038b4e4248e6ae320adc3ba0eb2695492 Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 22 Jan 2026 23:15:48 -0800 Subject: [PATCH 032/173] progress commit; sinatra 4.2.1 upgrade --- Gemfile | 2 +- Gemfile.lock | 2 +- config/logging.rb | 2 +- controllers/notes_controller.rb | 5 ++++- controllers/properties_search_controller.rb | 2 +- controllers/replies_controller.rb | 2 +- init.rb | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 5514e55a6..f26ce6807 100644 --- a/Gemfile +++ b/Gemfile @@ -94,4 +94,4 @@ group :test do gem 'simplecov-cobertura' # for codecov.io gem 'webmock' gem 'webrick' -end \ No newline at end of file +end diff --git a/Gemfile.lock b/Gemfile.lock index b37951f28..b269938f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: edddd813a857446314a00d283d162c5ce53f945d + revision: 326eb26687f7307b6ae7e6b8f2e215057606180e branch: ontoportal-lirmm-development specs: goo (0.0.2) diff --git a/config/logging.rb b/config/logging.rb index 03f2382ba..66c323a57 100644 --- a/config/logging.rb +++ b/config/logging.rb @@ -6,4 +6,4 @@ LOGGER = Logger.new(log_file) LOGGER.level = settings.development? ? Logger::DEBUG : Logger::INFO set :logger, LOGGER -end \ No newline at end of file +end diff --git a/controllers/notes_controller.rb b/controllers/notes_controller.rb index ab7742f21..e8dd7bdec 100644 --- a/controllers/notes_controller.rb +++ b/controllers/notes_controller.rb @@ -94,8 +94,10 @@ class NotesController < ApplicationController def note_from_params note_params = params.dup + note_params.delete("creator") proposal_params = clean_notes_hash(note_params.delete("proposal")) note = instance_from_params(LinkedData::Models::Note, clean_notes_hash(note_params)) + note.creator = current_user if proposal_params proposal = instance_from_params(LinkedData::Models::Notes::Proposal, proposal_params) @@ -121,4 +123,5 @@ def clean_notes_hash(hash) hash end end -end \ No newline at end of file +end + diff --git a/controllers/properties_search_controller.rb b/controllers/properties_search_controller.rb index 540aa0150..6c5b6cdfb 100644 --- a/controllers/properties_search_controller.rb +++ b/controllers/properties_search_controller.rb @@ -52,4 +52,4 @@ def process_search(params=nil) end end -end \ No newline at end of file +end diff --git a/controllers/replies_controller.rb b/controllers/replies_controller.rb index 1f63b54a7..88ffcd48d 100644 --- a/controllers/replies_controller.rb +++ b/controllers/replies_controller.rb @@ -82,4 +82,4 @@ class RepliesController < ApplicationController halt 204 end end -end \ No newline at end of file +end diff --git a/init.rb b/init.rb index ff7ee7c09..0fd644a9c 100644 --- a/init.rb +++ b/init.rb @@ -27,4 +27,4 @@ def self.registered(app) end end end -end \ No newline at end of file +end From 37530474f4d094d392a98f8721a070550b173ed4 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 27 Jan 2026 10:11:16 -0800 Subject: [PATCH 033/173] Gemfile.lock update --- Gemfile.lock | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6fed911a6..7d7c5b123 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 1a6d42628cfcf1704b96de45e27e81392333e343 + revision: 1b47e4f1b8494dfeb864b12f8fba3879fdd783d2 branch: master specs: ontologies_linked_data (0.0.1) @@ -109,18 +109,18 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) airbrussh (1.5.3) sshkit (>= 1.6.1, != 1.7.0) ast (2.4.3) backports (3.25.1) base64 (0.3.0) - bcrypt (3.1.20) + bcrypt (3.1.21) bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) - bigdecimal (3.3.1) + bigdecimal (4.0.1) builder (3.3.0) byebug (12.0.0) capistrano (3.19.2) @@ -136,13 +136,13 @@ GEM capistrano (~> 3.1) sshkit (~> 1.3) coderay (1.1.3) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) + concurrent-ruby (1.3.6) + connection_pool (2.5.5) crack (0.4.5) rexml cube-ruby (0.0.3) dante (0.2.0) - date (3.5.0) + date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) drb (2.2.3) @@ -153,8 +153,8 @@ GEM logger faraday-follow_redirects (0.4.0) faraday (>= 1, < 3) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) + faraday-net_http (3.4.2) + net-http (~> 0.5) faraday-retry (2.3.2) faraday (~> 2.0) ffi (1.17.2) @@ -248,9 +248,10 @@ GEM http-accept (1.7.0) http-cookie (1.1.0) domain_name (~> 0.5) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.15.2) + io-console (0.8.2) + json (2.18.0) json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) @@ -273,9 +274,9 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0924) + mime-types-data (3.2026.0113) mini_mime (1.1.5) - minitest (5.26.0) + minitest (5.27.0) minitest-bisect (1.7.0) minitest-server (~> 1.0) path_expander (~> 1.1) @@ -287,14 +288,14 @@ GEM minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis - multi_json (1.17.0) + multi_json (1.19.1) net-ftp (0.3.9) net-protocol time - net-http (0.7.0) - uri + net-http (0.9.1) + uri (>= 0.11.1) net-http-persistent (2.9.4) - net-imap (0.5.12) + net-imap (0.5.13) date net-protocol net-pop (0.1.2) @@ -310,7 +311,7 @@ GEM net-ssh (7.3.0) netrc (0.11.0) newrelic_rpm (9.19.0) - oj (3.16.12) + oj (3.16.13) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -326,9 +327,10 @@ GEM pony (1.13.1) mail (>= 2.0) prism (1.4.0) - pry (0.15.2) + pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) + reline (>= 0.6.0) public_suffix (6.0.2) racc (1.8.1) rack (1.6.13) @@ -355,7 +357,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.1) + redis-client (0.26.4) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -363,6 +365,8 @@ GEM redis-store (1.11.0) redis (>= 4, < 6) regexp_parser (2.10.0) + reline (0.6.3) + io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) rest-client (2.1.0) @@ -431,9 +435,9 @@ GEM temple (0.10.3) thread_safe (0.3.6) tilt (2.6.1) - time (0.4.1) + time (0.4.2) date - timeout (0.4.4) + timeout (0.6.0) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) From dae3e851b8894755a3d4e25c803a6cddfc26974c Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 27 Jan 2026 12:19:30 -0800 Subject: [PATCH 034/173] Gemfile.lock update --- Gemfile.lock | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6fed911a6..13ba7763a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 1a6d42628cfcf1704b96de45e27e81392333e343 + revision: 1b47e4f1b8494dfeb864b12f8fba3879fdd783d2 branch: master specs: ontologies_linked_data (0.0.1) @@ -109,18 +109,18 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) airbrussh (1.5.3) sshkit (>= 1.6.1, != 1.7.0) ast (2.4.3) backports (3.25.1) base64 (0.3.0) - bcrypt (3.1.20) + bcrypt (3.1.21) bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) - bigdecimal (3.3.1) + bigdecimal (4.0.1) builder (3.3.0) byebug (12.0.0) capistrano (3.19.2) @@ -136,13 +136,13 @@ GEM capistrano (~> 3.1) sshkit (~> 1.3) coderay (1.1.3) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) + concurrent-ruby (1.3.6) + connection_pool (2.5.5) crack (0.4.5) rexml cube-ruby (0.0.3) dante (0.2.0) - date (3.5.0) + date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) drb (2.2.3) @@ -153,8 +153,8 @@ GEM logger faraday-follow_redirects (0.4.0) faraday (>= 1, < 3) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) + faraday-net_http (3.4.2) + net-http (~> 0.5) faraday-retry (2.3.2) faraday (~> 2.0) ffi (1.17.2) @@ -248,9 +248,10 @@ GEM http-accept (1.7.0) http-cookie (1.1.0) domain_name (~> 0.5) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.15.2) + io-console (0.8.2) + json (2.18.0) json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) @@ -273,9 +274,9 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0924) + mime-types-data (3.2026.0127) mini_mime (1.1.5) - minitest (5.26.0) + minitest (5.27.0) minitest-bisect (1.7.0) minitest-server (~> 1.0) path_expander (~> 1.1) @@ -287,14 +288,14 @@ GEM minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis - multi_json (1.17.0) + multi_json (1.19.1) net-ftp (0.3.9) net-protocol time - net-http (0.7.0) - uri + net-http (0.9.1) + uri (>= 0.11.1) net-http-persistent (2.9.4) - net-imap (0.5.12) + net-imap (0.5.13) date net-protocol net-pop (0.1.2) @@ -310,7 +311,7 @@ GEM net-ssh (7.3.0) netrc (0.11.0) newrelic_rpm (9.19.0) - oj (3.16.12) + oj (3.16.13) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -326,9 +327,10 @@ GEM pony (1.13.1) mail (>= 2.0) prism (1.4.0) - pry (0.15.2) + pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) + reline (>= 0.6.0) public_suffix (6.0.2) racc (1.8.1) rack (1.6.13) @@ -355,7 +357,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.1) + redis-client (0.26.4) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -363,6 +365,8 @@ GEM redis-store (1.11.0) redis (>= 4, < 6) regexp_parser (2.10.0) + reline (0.6.3) + io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) rest-client (2.1.0) @@ -431,9 +435,9 @@ GEM temple (0.10.3) thread_safe (0.3.6) tilt (2.6.1) - time (0.4.1) + time (0.4.2) date - timeout (0.4.4) + timeout (0.6.0) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) From e91f1b201aff6e54fe297ad086ae074502596485 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 27 Jan 2026 22:53:37 -0800 Subject: [PATCH 035/173] added solr admin endpoints --- controllers/admin_controller.rb | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/controllers/admin_controller.rb b/controllers/admin_controller.rb index d6a23b90a..b16a92a2c 100644 --- a/controllers/admin_controller.rb +++ b/controllers/admin_controller.rb @@ -127,6 +127,79 @@ class AdminController < ApplicationController halt 204 end + namespace "/search" do + get '/collections' do + conn = SOLR::SolrConnector.new(Goo.search_conf, '') + collections = { collections: conn.fetch_all_collections} + reply(200, collections) + end + + get '/collections/:collection/schema' do + collection = params[:collection].to_sym + conn = SOLR::SolrConnector.new(Goo.search_conf, collection) + collection_schema = conn.fetch_schema + + reply(200, collection_schema) + end + + post '/collections/:collection/schema/init' do + collection = params[:collection].to_sym + conn = SOLR::SolrConnector.new(Goo.search_conf, collection) + collection_schema = conn.init_schema + reply(200, collection_schema) + end + + post '/collections/:collection/search' do + collection = params[:collection].to_sym + + search_keys = %w[defType fq qf sort start rows fl stopwords lowercaseOperators] + + search_params = params.select { |key, _| search_keys.include?(key) } + search_query = params[:query] || params[:q] + search_query = search_query.blank? ? '*' : search_query + conn = SOLR::SolrConnector.new(Goo.search_conf, collection) + reply(200, conn.search(search_query, search_params).to_h) + end + + post '/index_batch/:model_name' do + error 500, "model_name parameter not set" if params["model_name"].blank? + + model = Goo.model_by_name(params["model_name"].to_sym) + error 500, "#{params["model_name"]} is not indexable" if model.nil? || !model.index_enabled? + + all_attrs = get_attributes_to_include([:all], model) + + collections = model.where.include(all_attrs).all + indexed = [] + not_indexed = [] + collections.each do |m| + begin + response = m.index.dig("responseHeader", "status") + if response.eql?(0) + indexed << m.id + else + not_indexed << m.id + end + rescue StandardError + not_indexed << m.id + end + end + + if !indexed.empty? + msg = "Batch indexing for #{model.model_name} completed for" + + if not_indexed.empty? + msg += " all models" + else + msg += " #{indexed.join(', ')} and not for the following #{not_indexed.join(', ')}, see logs for more details" + end + reply(200, msg) + else + reply(500, "Batch indexing for #{model.model_name} failed") + end + end + end + private def redis_goo From a15ccfd2d6b712ed6f4249a935db90756a1c45fe Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 27 Jan 2026 22:56:21 -0800 Subject: [PATCH 036/173] synchronized test ontology files with AgroPortal --- test/data/ontology_files/BRO_v3.2.owl | 1282 +++++++------ .../CellLine_OWL_BioPortal_v1.0.owl | 1699 ++++++++--------- 2 files changed, 1489 insertions(+), 1492 deletions(-) diff --git a/test/data/ontology_files/BRO_v3.2.owl b/test/data/ontology_files/BRO_v3.2.owl index 33e91d797..c083fb3d3 100644 --- a/test/data/ontology_files/BRO_v3.2.owl +++ b/test/data/ontology_files/BRO_v3.2.owl @@ -44,10 +44,10 @@ - - - + @@ -64,7 +64,7 @@ Definition definition - + @@ -73,28 +73,28 @@ replacedBy - + - + - + - - - + @@ -113,7 +113,7 @@ Scientific purpose of algorithm - + @@ -124,7 +124,7 @@ What are the goals of the document - + @@ -134,7 +134,7 @@ InteractionType What type of interaction is this? - + @@ -145,7 +145,7 @@ what kind of information is being capture in this measurement? - + @@ -156,7 +156,7 @@ What form of output is produced by this thing - + @@ -168,7 +168,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -198,7 +198,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -227,7 +227,7 @@ replacedBy - + @@ -239,7 +239,7 @@ - + @@ -250,10 +250,10 @@ - - - + @@ -271,7 +271,7 @@ Any kind of identifier Identifier - + @@ -280,7 +280,7 @@ Implementation_Language Implementation Language - + @@ -291,7 +291,7 @@ Originator of a class - + @@ -301,7 +301,7 @@ Other Information - + @@ -312,7 +312,7 @@ is this a peer-reviewed scientific publication? - + @@ -322,7 +322,7 @@ ProteinType broad classification of protein type based on structure or function - + @@ -331,7 +331,7 @@ Target_User_Type Target User Type - + @@ -341,7 +341,7 @@ TranscriptType Type of biological transcript - + @@ -352,7 +352,7 @@ - + @@ -363,7 +363,7 @@ - + @@ -373,7 +373,7 @@ true - + @@ -385,7 +385,7 @@ - + @@ -397,7 +397,7 @@ - + @@ -407,7 +407,7 @@ contact person email - + @@ -418,7 +418,7 @@ - + @@ -428,7 +428,7 @@ definition - + @@ -440,7 +440,7 @@ - + @@ -452,7 +452,7 @@ - + @@ -462,7 +462,7 @@ true - + @@ -474,7 +474,7 @@ - + @@ -486,7 +486,7 @@ - + @@ -498,7 +498,7 @@ - + @@ -510,7 +510,7 @@ - + @@ -520,7 +520,7 @@ true - + @@ -532,7 +532,7 @@ - + @@ -544,7 +544,7 @@ - + @@ -554,7 +554,7 @@ release date - + @@ -566,7 +566,7 @@ - + @@ -578,7 +578,7 @@ - + @@ -590,7 +590,7 @@ - + @@ -601,7 +601,7 @@ - + @@ -613,10 +613,10 @@ - - - + @@ -638,19 +638,19 @@ Activité d’intérêt pouvant être liée à un BRO:Resource. activities - + + Activity related to the creation, use, or maintenance of a biorepository (http://en.wikipedia.org/wiki/Biorepository) + Biospecimen Management Activity related to the creation, use, or maintenance of a biorepository (http://en.wikipedia.org/wiki/Biorepository) Activité liée à la création, à l'utilisation ou à la maintenance d'un bioréférentiel (http://en.wikipedia.org/wiki/Biorepository) - Biospecimen Management - Gestion des échantillons biologiques - + @@ -658,9 +658,8 @@ As defined in http://en.wikipedia.org/wiki/Community_engagement - Community Engagement - + @@ -670,7 +669,7 @@ Former subclasses of activity:Activity that have been deprecated and their usage is not recommended. true - + @@ -678,9 +677,9 @@ As defined in http://en.wikipedia.org/wiki/Gene_therapy - Gene Therapy + Gene Therapy - + @@ -690,7 +689,7 @@ As defined in http://en.wikipedia.org/wiki/Health_services_research Health Services - + @@ -703,7 +702,7 @@ true - + @@ -714,7 +713,7 @@ Tag as a resource for a specific Institutional Review Board (http://en.wikipedia.org/wiki/Institutional_Review_Board) 0123456789 - + @@ -724,7 +723,7 @@ As defined in http://en.wikipedia.org/wiki/Medical_device Medical Device Development - + @@ -737,7 +736,7 @@ true - + @@ -747,7 +746,7 @@ As defined in http://en.wikipedia.org/wiki/Regulatory_compliance Regulatory Compliance - + @@ -757,7 +756,7 @@ Activity related to learning about, securing, and managing money to support research Research Funding - + @@ -767,7 +766,7 @@ Management and communications within the laboratory setting (http://www.umuc.edu/programs/undergrad/certificates/lab_mgmt.shtml) Research Lab Management - + @@ -777,7 +776,7 @@ Activity related to gathering and inventory of resources, e.g., biositemaps Resource Inventory - + @@ -787,7 +786,7 @@ As defined in http://en.wikipedia.org/wiki/Small_molecule Small Molecule - + @@ -797,7 +796,7 @@ As defined in http://en.wikipedia.org/wiki/Social_network Social Networking - + @@ -806,7 +805,7 @@ Software Development - + @@ -816,7 +815,7 @@ Methods used in the medical specialty of surgery, as defined in http://en.wikipedia.org/wiki/Surgical_procedure Surgical Procedure - + @@ -826,7 +825,7 @@ Innovative therapeutics (http://en.wiktionary.org/wiki/therapeutics) Therapeutics - + @@ -836,7 +835,7 @@ As defined in http://en.wikipedia.org/wiki/Training Training - + @@ -846,7 +845,7 @@ A resource that provides data from clinical care that comprises combined data from multiple individual human subjects. Aggregate Human Data - + @@ -856,7 +855,7 @@ Algorithm Resource that provides access to software or application that perform numerical analysis or other canonical computational methods that act either on experimental or synthetic data. - + @@ -867,7 +866,7 @@ An instrument that increases the output of another instrument. pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -877,7 +876,7 @@ Analysis of Gel-Electrophoresis Resource that provides access to software, applications, or toolkits that can be used to provide quantitative data on the molecules being analyzed such as molecular weight, abundance or purity. - + @@ -890,7 +889,7 @@ true - + @@ -901,7 +900,7 @@ Animal Care Facility pending final vetting: Refine definition - + @@ -911,7 +910,7 @@ A resource which can include a committee or a board that reviews research protocols and conducts evaluations of the animal care facilities. The resource can be used to ensure the use of animals in research follows the required legal and ethical guidelines. Animal Compliance Resource - + @@ -922,7 +921,7 @@ Animal Models Facility pending final vetting: Refine definition - + @@ -932,7 +931,7 @@ A resource that provides access to the ability to generate antibodies that bind to a specific antigen. Antibody Production - + @@ -942,7 +941,7 @@ Application Programming Interface Resource that provides access to software, application, or toolkit that enables or can be used to develop application programming interfaces. - + @@ -953,7 +952,7 @@ Approximate Graph Alignment Resource that provides access to software, applications, or toolkits that allows insertions, deletions, or mismatches in nodes/edges. - + @@ -963,7 +962,7 @@ A resource that provides access to scientific data assessment instruments, for example behavioral assessment tests. Assessment Material Resource - + @@ -973,7 +972,7 @@ A resource that provides anatomical data represented by spatially indexed anatomical maps. Atlas - + @@ -983,7 +982,7 @@ Atlas Generation Resource that provides access to software, applications, or toolkits that generate computational atlases of biological objects using imaging techniques. - + @@ -993,7 +992,7 @@ Authentication The process of confirming the correctness of the claimed identity. - + @@ -1003,7 +1002,7 @@ Authorization The process of specifying access rights to a resource. - + @@ -1016,7 +1015,7 @@ true - + @@ -1026,7 +1025,7 @@ Averaging and Agglomeration Resource that provides access to software, applications, or toolkits that performs signal processing by repeated measures of the signal and then calculates the expected value of the data set. - + @@ -1039,7 +1038,7 @@ true - + @@ -1049,7 +1048,7 @@ A resource that provides long-term storage for back-up copies of files. Backup Archive Service - + @@ -1063,7 +1062,7 @@ - + @@ -1074,7 +1073,7 @@ Behavioral Analysis Service pending final vetting: review hierarchy location - + @@ -1085,7 +1084,7 @@ Bibliographic Resource - + @@ -1098,7 +1097,7 @@ true - + @@ -1108,7 +1107,7 @@ A facility or core that provides storage for any type of biospecimen. Biobank Facility - + @@ -1121,7 +1120,7 @@ true - + @@ -1131,7 +1130,7 @@ A resource that provides data from any biomaterial sample that was given to the service provider. This can also be a service that performs an experiment such as electrophysiological examination of LTP in a transgenic mouse. Viewing this as an input/output relationship the input would be a tissue or an animal and the output would be data. Biomaterial Analysis Service - + @@ -1141,7 +1140,7 @@ A resource that produces a product that is of organismal origin. An example of a biomaterial service is the production of a knockout mouse or cell culture. Note, for simplicity of definitions all molecules including antibodies and toxins are considered reagents even though some may have an organismal origin. Biomaterial Manufacture - + @@ -1151,7 +1150,7 @@ A resource that provides access to physical materials like tissue samples or organisms. For example, the IMSR enables acquisition of a transgenic mouse or cell line. Note, for the sake of simplicity we have excluded molecules of organismal origin from this category as these can be manufactured chemically and have included them under the reagent category (eg. antibodies, toxins). Biomaterial Supply Resource - + @@ -1162,7 +1161,7 @@ Biomedical Supply Resource pending final vetting: suggest to deprecate - + @@ -1173,7 +1172,7 @@ Biomolecular Interaction Facility pending final vetting: Refine definition - + @@ -1183,7 +1182,7 @@ A resource that provides access to an enclosed facility that takes specified precautions for containment of dangerous biological agents, as defined by http://en.wikipedia.org/wiki/Biosafety_level Biosafety Level Facility - + @@ -1193,7 +1192,7 @@ A resource that provides access to a written or printed work of fiction or nonfiction, usually on sheets of paper fastened or bound together within covers. Book - + @@ -1203,7 +1202,7 @@ Bug Reporting Resource that provides access to software, application, or toolkit that enable web-based tools that provide structure to indicate a problem or issue. Typically, bug reporting software provides a mechanism to indicate the severity of the problem and a contact person to review the issue. - + @@ -1215,7 +1214,7 @@ CT Scanner pending final vetting: location in hierarchy and harmonize with OBI/eagle-i - + @@ -1225,7 +1224,7 @@ Calculation of Solvent Accessible Area Resource that provides access to software, applications, or toolkits that can be used to determine the surface area of a molecule such as DNA or protein. - + @@ -1235,7 +1234,7 @@ A resource that provides functionality to allocate resources based on a method of timekeeping. Calendar Schedule and Resource Management - + @@ -1246,7 +1245,7 @@ Calorimeter pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -1257,7 +1256,7 @@ Cardiovascular Facility pending final vetting: Refine definition - + @@ -1267,7 +1266,7 @@ Cardiovascular Model Resource that provides access to software, applications, or toolkits that can be used to model physiological processes of the cardiovascular system. - + @@ -1277,7 +1276,7 @@ A resource that provides access to instruments, technologies, facilities, and/or expert support devoted to cell biology (http://en.wikipedia.org/wiki/Cell_biology) research Cell Biology Facility - + @@ -1287,7 +1286,7 @@ A facility or core that provides resources for the growth of cells. Cell Culture Facility - + @@ -1297,7 +1296,7 @@ Cell Model Resource that provides access to software, applications, or toolkits that model the processes of a cell. - + @@ -1307,7 +1306,7 @@ A resource that provides access to an enclosed environment that has a low and controlled level of environmental pollutants such as dust, airborne microbes, aerosol particles and chemical vapors. Cell Processing Clean Room Facility - + @@ -1320,7 +1319,7 @@ true - + @@ -1330,7 +1329,7 @@ A Resource that provides access to a graph algorithm that uses ranking of network elements to identify the importance of elements in a network. Centrality Analysis - + @@ -1340,7 +1339,7 @@ A resource that provides a document that certifies completion of the program. Certificate Program - + @@ -1351,7 +1350,7 @@ Chamber pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -1361,7 +1360,7 @@ A resource that provides any type of data obtained in the course of caring for humans outside of measurements obtained in clinical trials. Clinical Care Data - + @@ -1375,7 +1374,7 @@ we think this should be deleted true - + @@ -1389,7 +1388,7 @@ we think this should be deleted true - + @@ -1402,7 +1401,7 @@ we think this should be deleted true - + @@ -1412,7 +1411,7 @@ we think this should be deleted A resource that provides data on clinical trials and outcomes studies. Clinical Research Data - + @@ -1425,7 +1424,7 @@ we think this should be deleted true - + @@ -1435,7 +1434,7 @@ we think this should be deleted A resource that provides a performance analysis tool that measures the behavior of a program as it executes, particularly the frequency and duration of function calls. The profiling process helps to determine which subroutines (or just snippets of code) take longest to execute and which subroutines are called most often. Code profilers are used when you suspect that some part of your code is called very often and maybe there is a need to optimize it, which could significantly improve the overall performance. Profilers use a wide variety of techniques to collect data, including hardware interrupts, code instrumentation, instruction set simulation, operating system hooks, and performance counters. Code Profiler - + @@ -1445,7 +1444,7 @@ we think this should be deleted A resource that provides a software environment created to investigate the quality of the product or service under test, with respect to the context in which it is intended to operate. This includes, but is not limited to, the process of executing a program or application with the intent of finding software bugs. Code Testing Framework - + @@ -1455,7 +1454,7 @@ we think this should be deleted Communication Interface Resource that provides access to software, applications, or toolkits that enable electronic communication. - + @@ -1465,7 +1464,7 @@ we think this should be deleted Communication and Collaborative Work Resource that provides access to software, application, or toolkit that has mechanisms for sharing information between members of a group working on a shared project. - + @@ -1475,7 +1474,7 @@ we think this should be deleted Community Structure Analysis Resource that provides access to a graph algorithm that identifies densely interlinked nodes in the graph. - + @@ -1485,7 +1484,7 @@ we think this should be deleted A resource that provides a computer program (or set of programs) that transforms source code written in a computer language (the source language) into another computer language (the target language, often having a binary form known as object code). The most common reason for wanting to transform source code is to create an executable program. A \\u201ccompiler\\u201d is primarily used for programs that translate source code from a high-level programming language to a lower level language (e.g., assembly language or machine language), and is likely to perform many or all of the following operations: lexical analysis, pre-processing, parsing, semantic analysis, code generation, and code optimization. Compiler - + @@ -1496,7 +1495,7 @@ we think this should be deleted Computational Geometry Resource that provides access to tools for computational geometric representation and analysis. - + @@ -1507,7 +1506,7 @@ we think this should be deleted Computational Hosting pending final vetting: propose definition - + @@ -1517,7 +1516,7 @@ we think this should be deleted A resource that provides a simplified or symbolic representation of a system or phenomenon. Computational Model - + @@ -1527,7 +1526,7 @@ we think this should be deleted A resource that provides support for computer-related services such as database hosting and backup and disaster recovery. Computational Service - + @@ -1538,7 +1537,7 @@ we think this should be deleted Computer-Instrumentation Interface pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -1548,7 +1547,7 @@ we think this should be deleted A resource the provides access to papers and/or talk and poster abstracts that are presented at a conference. Conference Proceeding - + @@ -1558,7 +1557,7 @@ we think this should be deleted A resource that develops policies and procedures related to associations between academia and industry to ensure that the advantages of these connections are not being achieved at the expense of the fundamental values of objectivity in research. Conflict of Interest Resource - + @@ -1571,7 +1570,7 @@ we think this should be deleted true - + @@ -1581,7 +1580,7 @@ we think this should be deleted Contact Modeling Resource that provides access to software, applications, or toolkits that simulate the effect of contact between objects. For example an articular contact model to study articular surface stresses. - + @@ -1591,7 +1590,7 @@ we think this should be deleted A resource that provides post-grad education for physicians. Continuing Medical Education - + @@ -1604,7 +1603,7 @@ we think this should be deleted true - + @@ -1614,7 +1613,7 @@ we think this should be deleted Continuum Method Simulation Resource that provides access to software, applications, or toolkits that uses all data points in a simulation. - + @@ -1624,7 +1623,7 @@ we think this should be deleted Controllers Resource that provides access to software, applications, or toolkits that use controllers in the performance of a simulation. - + @@ -1635,7 +1634,7 @@ we think this should be deleted Convolution Resource the provides access to tools or functions that implements the canonical convolution or operation that describes the action of a linear system on a signal. - + @@ -1645,7 +1644,7 @@ we think this should be deleted Cortical Modeling Resource that provides access to software, applications, or toolkits that perform detection, extraction, representation and analysis of cortical brain structure. - + @@ -1655,7 +1654,7 @@ we think this should be deleted Course Material Resource that provides access to educational material that can be used to disseminate information about a course of study. - + @@ -1665,7 +1664,7 @@ we think this should be deleted Cross-Language Wrapping Resource that provides access to software, application, or toolkit that enables an interactive software development tool that creates language bindings. - + @@ -1675,7 +1674,7 @@ we think this should be deleted Cross-Platform Tool Resource that provides access to software, application, or toolkit that enables an interactive software development tool that runs on different computer operating systems. - + @@ -1685,7 +1684,7 @@ we think this should be deleted Cross-Sectional Viewer Resource that provides access to data visualization tools relying on displays of lower-dimensional cross-sectional (hyper)planes. - + @@ -1696,7 +1695,7 @@ we think this should be deleted Resource that provides access to software or application that support collection of real-world conditions and converts these to a numerical representation that can be processed by a computer, http://en.wikipedia.org/wiki/Data_acquisition. pending final vetting: review term in comparison to siblings data analysis software and data processing software - + @@ -1706,7 +1705,7 @@ we think this should be deleted A resource that provides access to software or application that is used to analyze, model, and transform data with the goal of testing a research hypothesis, highlighting useful information, suggesting conclusions, or supporting decision making. Data Analysis Software - + @@ -1716,7 +1715,7 @@ we think this should be deleted Data Annotation Resource that provides access an interactive software tool that enables tagging data with ontology terms. - + @@ -1726,7 +1725,7 @@ we think this should be deleted Data Compression Resource that provides access to software, applications, or toolkits that reduces the bits (information units) needed to encode the data. - + @@ -1736,7 +1735,7 @@ we think this should be deleted A resource that provides calculating or processing over a data input, such as interpreting EEG data. Note, this may include human and/or computer expertise, so that a software tool may be included as a data computation service. Data Computation Service - + @@ -1749,7 +1748,7 @@ we think this should be deleted true - + @@ -1759,7 +1758,7 @@ we think this should be deleted Data Editor Resource that provides access to software, application, or toolkit that is able to alter information. - + @@ -1769,7 +1768,7 @@ we think this should be deleted Data Exploration Resource that provides access to a visualization tool that is able to display data as an image or graphical representation. - + @@ -1781,7 +1780,7 @@ we think this should be deleted Data Mining and Inference pending final vetting: review location in hierarchy and child terms - + @@ -1791,7 +1790,7 @@ we think this should be deleted Data Normalization Resource that provides access to software, applications, or toolkits that reduces systematic sources of variation from data. - + @@ -1804,7 +1803,7 @@ we think this should be deleted true - + @@ -1814,7 +1813,7 @@ we think this should be deleted A resource that provides access to software or application that is used to convert or manipulate data into information or knowledge. Data Processing Software - + @@ -1827,7 +1826,7 @@ we think this should be deleted true - + @@ -1837,7 +1836,7 @@ we think this should be deleted A resource that provides individual facts, statistics or items of information. Data Resource - + @@ -1848,7 +1847,7 @@ we think this should be deleted Data Service pending final vetting: review location in hierarchy - + @@ -1862,7 +1861,7 @@ we think this should be deleted - + @@ -1875,7 +1874,7 @@ we think this should be deleted true - + @@ -1885,7 +1884,7 @@ we think this should be deleted A resource that provides data storage and maintenance, such as a database that accepts submissions of similar data for storage and use. For example, the cell centered database (CCDB) encourages submissions of anatomical images that will increase its' holdings. Data Storage Service - + @@ -1895,7 +1894,7 @@ we think this should be deleted A resource that provides access to software or application that is used to transmit formatted textual or binary data. Data Transfer and Communication - + @@ -1905,7 +1904,7 @@ we think this should be deleted Data Transform Resource that provides access to software, applications, or toolkits that general data transformations. - + @@ -1918,7 +1917,7 @@ we think this should be deleted true - + @@ -1928,7 +1927,7 @@ we think this should be deleted Data Visualization Resource that provides access to software, applications, or toolkits that present information as an image. - + @@ -1939,7 +1938,7 @@ we think this should be deleted Data Repository Database - + @@ -1949,7 +1948,7 @@ we think this should be deleted A resource that provides space for and access to a database. Database Hosting - + @@ -1959,7 +1958,7 @@ we think this should be deleted A resource that provides access to software, applications, or toolkits that are used in the development of database management systems. Database Software - + @@ -1969,7 +1968,7 @@ we think this should be deleted Deep Parsing Resource that provides access to applications, libraries, or software that detect relationships between language constructs. - + @@ -1979,7 +1978,7 @@ we think this should be deleted A resource that provides access to structured data that is separated by a sequence of one or more characters to mark the boundary between plain text or data streams. Delimited Table - + @@ -1991,7 +1990,7 @@ we think this should be deleted Former subclasses of BRO:Data_Resource that have been deprecated and their usage is not recommended. true - + @@ -2001,7 +2000,7 @@ we think this should be deleted Former subclasses of BRO:Resource that have been deprecated and their usage is not recommended. true - + @@ -2011,7 +2010,7 @@ we think this should be deleted A resource that provides the ability to retrieve archived content in the event of a disaster that impacts the system in question. Disaster Recovery Service - + @@ -2024,7 +2023,7 @@ we think this should be deleted true - + @@ -2034,7 +2033,7 @@ we think this should be deleted Dissemination Vehicle Resource that provides access to Community and User Interaction Systems, educational resources and web-services. - + @@ -2047,7 +2046,7 @@ we think this should be deleted true - + @@ -2057,7 +2056,7 @@ we think this should be deleted Document Generation Resource that provides access to software, application, or toolkit that enables a software development tool that is able to generate textual information when included in computer source code as specially formatted comments. - + @@ -2068,7 +2067,7 @@ we think this should be deleted Resource that provides access to software, applications, or toolkits that provides an electronic document or file in response to a query. pending final vetting: review location in hierarchy - + @@ -2078,7 +2077,7 @@ we think this should be deleted Document Structure Parsing Resource that provides access to applications, libraries, or software that analyze and report on document structure. - + @@ -2088,7 +2087,7 @@ we think this should be deleted Documentation Generation Resource that provides access to software, application, or toolkit that enables a software development tool create documentation of software source code. - + @@ -2099,7 +2098,7 @@ we think this should be deleted Drug Delivery Device pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -2109,7 +2108,7 @@ we think this should be deleted A resource that provides a simplified or symbolic representation representing the states of a system or network over time. Dynamic Model - + @@ -2122,7 +2121,7 @@ we think this should be deleted true - + @@ -2132,7 +2131,7 @@ we think this should be deleted Education Resource that provides access to educational resources (incl. book, magazines, audio, video, digital streams, etc.), - + @@ -2143,7 +2142,7 @@ we think this should be deleted Electrode Holder pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -2154,7 +2153,7 @@ we think this should be deleted Electrode Puller pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -2166,7 +2165,7 @@ we think this should be deleted Electron Microscope In version 3.2 pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -2176,7 +2175,7 @@ we think this should be deleted A resource that provides services to ensure research is conducted in accordance with environmental and safety standards (e.g. laboratory safety procedures, radiation safety procedures, disposal protocols, etc). Environmental Health and Safety Resource - + @@ -2189,7 +2188,7 @@ we think this should be deleted true - + @@ -2199,7 +2198,7 @@ we think this should be deleted A resource that provides detailed plans for a scientific experiments, medical trials, or other pieces of research. Experimental Protocol - + @@ -2212,7 +2211,7 @@ we think this should be deleted true - + @@ -2222,7 +2221,7 @@ we think this should be deleted Exploratory Data Analysis Resource that provides access to software, applications, or toolkits that performs exploratory data analysis methods. - + @@ -2232,7 +2231,7 @@ we think this should be deleted A facility core devoted to creating, manufacturing, building or assembling resources used in scientific research. Fabrication Facility - + @@ -2245,7 +2244,7 @@ we think this should be deleted Facility Core pending final vetting: suggest to re-name to Core Facility, discuss how to manage change. - + @@ -2256,7 +2255,7 @@ we think this should be deleted Faraday Cage pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -2267,7 +2266,7 @@ we think this should be deleted Fast Fourier Transform Resource that provides access to tools or functions that compute the discrete Fourier transform (DFT) and its inverse. - + @@ -2277,7 +2276,7 @@ we think this should be deleted Feature Analysis Resource that provides access to methods for automated analysis of object features and quantitative characterization of data. - + @@ -2287,7 +2286,7 @@ we think this should be deleted Feature Request Resource that provides access to software, application, or toolkit that enable interactive web-based tool that has functionality to collect a request for new features for a specified tool. - + @@ -2297,7 +2296,7 @@ we think this should be deleted A funding resource where money is obtained from the central government. Federal Funding Resource - + @@ -2307,7 +2306,7 @@ we think this should be deleted Filtering Resource that provides access to software, applications, or toolkits that perform alter the spatial-temporal spectral content of data. - + @@ -2317,7 +2316,7 @@ we think this should be deleted Finite Element Model Resource that provides access to software, applications, or toolkits that can be used to generate approximate solutions of partial differential equations. - + @@ -2327,7 +2326,7 @@ we think this should be deleted A resource that provides access to structured data that is found in separate, unlinked files that is accessible via the internet. Flatfile Distribution - + @@ -2338,7 +2337,7 @@ we think this should be deleted Flow Cytometry Cell Sorting Facility pending final vetting: consider changing name to Flow Cytometry Facility - + @@ -2351,7 +2350,7 @@ we think this should be deleted true - + @@ -2361,7 +2360,7 @@ we think this should be deleted Fourier Transform Resource that provides access to software, applications, or toolkits that performs Multi-dimensional Fourier transform - + @@ -2374,7 +2373,7 @@ we think this should be deleted true - + @@ -2388,7 +2387,7 @@ we think this should be deleted http://bioportal.bioontology.org/ontologies/umls/sty/T028 pending final vetting: are more subclasses needed, e.g. Foreign_Funding_Resource and Local_Funding_Resource - + @@ -2398,7 +2397,7 @@ we think this should be deleted A resource that provides data on the abundance of RNA that is coded from genes. Gene Expression - + @@ -2408,7 +2407,7 @@ we think this should be deleted A facility or core for generating recombinant vectors containing a functioning copy of a human gene. Gene Therapy Facility - + @@ -2420,7 +2419,7 @@ we think this should be deleted Genomic Phenotypic Analysis - + @@ -2431,7 +2430,7 @@ we think this should be deleted Genomics Facility pending final vetting: Refine definition - + @@ -2441,7 +2440,7 @@ we think this should be deleted A resource the provides access to a publicly available document that is generated by a governing entity. Government Publication - + @@ -2452,7 +2451,7 @@ we think this should be deleted Grant Preparation Expertise pending final vetting: refine definition - + @@ -2462,7 +2461,7 @@ we think this should be deleted Graph Algorithm Resource that provides access to methods of analysis or generation of networks and graph data structures. - + @@ -2472,7 +2471,7 @@ we think this should be deleted Graph Alignment Resource that provides access to a graph algorithm that compares the similarity of graphs to each other. - + @@ -2482,7 +2481,7 @@ we think this should be deleted Graph Analysis Resource that provides access to software, applications, or toolkit that analyze biological graphs. - + @@ -2492,7 +2491,7 @@ we think this should be deleted Graph Viewer Resource that provides access to general graph visualization methods. - + @@ -2505,7 +2504,7 @@ we think this should be deleted true - + @@ -2515,7 +2514,7 @@ we think this should be deleted Graphical Composition Resource that provides access to software, application, or toolkit that enable graphical composition of applications. - + @@ -2525,7 +2524,7 @@ we think this should be deleted Graphical Integration Resource that provides access to software, application, or toolkit that enables software or application integration using graphical methods. - + @@ -2536,7 +2535,7 @@ we think this should be deleted Resource that provides access to software, applications, or toolkits that enable integration and interoperability tools that facilitate communication between software tools via graphical workflow pipelines. pending final vetting: review definition - + @@ -2546,7 +2545,7 @@ we think this should be deleted A resource that provides a combination of computational resources from multiple administrative domains, applied to a common task. Grid Computing - + @@ -2556,7 +2555,7 @@ we think this should be deleted Heat Map Resource that provides access to an interactive visualization tool that represents variables in a 2-D graph as colors. - + @@ -2569,7 +2568,7 @@ we think this should be deleted true - + @@ -2579,7 +2578,7 @@ we think this should be deleted Hierarchical Tree Resource that provides access to viewers of directed, acyclic tree-structures. - + @@ -2592,7 +2591,7 @@ we think this should be deleted true - + @@ -2602,7 +2601,7 @@ we think this should be deleted Homology Modeling Resource that provides access to software, applications, or toolkits that uses a proteins amino acid sequence and an experimental three-dimensional structure of a related homologous protein to generate an atomic-resolution model of the protein. - + @@ -2612,7 +2611,7 @@ we think this should be deleted A resource that provides a server for data or programs that another computer can access by means of a network. Hosting - + @@ -2622,7 +2621,7 @@ we think this should be deleted A resource that provides guidance and information regarding the use of embryos or human embryonic stem cells in research. Human Embryonic Stem Cell Resource - + @@ -2632,7 +2631,7 @@ we think this should be deleted A resource that provides guidelines and information related to research involving humans with the aim to protect the rights and welfare of research subjects. Such resources could supply consent forms, patient questionnaires, assist in ethical protocol designs, host seminars on conducting human studies, etc. Human Studies Compliance Resource - + @@ -2642,7 +2641,7 @@ we think this should be deleted Hyperbolic Graph Resource that provides access to hyperbolic space (hierarchical) graph/tree visualization tools. - + @@ -2652,7 +2651,7 @@ we think this should be deleted Hypothesis Testing Algorithm Resource that provides access to tools or functions for testing statistical hypothesis against data. - + @@ -2662,7 +2661,7 @@ we think this should be deleted A resource that provides software which maintains the identity of a software user with their software account. Identity Management - + @@ -2673,7 +2672,7 @@ we think this should be deleted Image pending final vetting: review location in hierarchy - + @@ -2683,7 +2682,7 @@ we think this should be deleted Image Algorithm Resource that provides access to methods basic numerical analysis or other canonical computational methods that act on 1, 2, 3 or 4 dimensional images. - + @@ -2694,7 +2693,7 @@ we think this should be deleted Resource that provides access to software, applications, or toolkits that performs image post processing (i.e., excludes image generation). pending final vetting: review location in hierarchy - + @@ -2704,7 +2703,7 @@ we think this should be deleted A resource that provides access to tools or function that are used to reconstruct 2D and 3D images based on projections of an object. Image Reconstruction - + @@ -2715,7 +2714,7 @@ we think this should be deleted Resource that provides access to software, application, or toolkit that enable visualization methods for imaging data. pending final vetting: rename this Imaging_Software (at least as it occurs in Software tree)? - + @@ -2725,7 +2724,7 @@ we think this should be deleted A facility or core for biomedical imaging. Imaging Facility - + @@ -2735,7 +2734,7 @@ we think this should be deleted A facility or core devoted to assessing effects on the human immune system (immunogenicity, immunocompetence, immune reconstitution, immunotoxicity, and immunopathology) of particular importance in the study of disease and therapeutics. Immune Monitoring Facility - + @@ -2745,7 +2744,7 @@ we think this should be deleted A facility or core devoted to localizing antigens (eg. proteins) in cells of a tissue section through antibodies binding specifically to antigens. Immunohistochemistry Facility - + @@ -2755,7 +2754,7 @@ we think this should be deleted A resource that provides clinical care data at the level of an individual. Individual Human Data - + @@ -2766,7 +2765,7 @@ we think this should be deleted Industry Partnership Expertise pending final vetting: refine definition - + @@ -2776,7 +2775,7 @@ we think this should be deleted Inference From Data Resource that provides access to software, applications, or toolkits, that generate a conclusion or finding based on applying logics and statistics to observations/hypothesis. - + @@ -2788,7 +2787,7 @@ we think this should be deleted Information Resource hasDbXref0000001 - + @@ -2798,7 +2797,7 @@ we think this should be deleted Information Retrieval Resource that provides access to software, applications, or toolkits that searches documents for information within the document and metadata about the document. - + @@ -2808,7 +2807,7 @@ we think this should be deleted Inhomogeneity Correction Resource that provides access to software, applications, or toolkits that performs methods for correction of image intensities where non-biological and non-physiological drift or noise is introduced by the scanning hardware. - + @@ -2819,7 +2818,7 @@ we think this should be deleted Instrument pending final vetting: review scope of BRO for child terms - + @@ -2829,7 +2828,7 @@ we think this should be deleted A resource that provides the manufacture of a piece of hardware. An example is producing a made to order microarray chip. Instrument Manufacture - + @@ -2840,7 +2839,7 @@ we think this should be deleted Integrated Hosting pending final vetting: refine definition - + @@ -2850,7 +2849,7 @@ we think this should be deleted Integration Resource that provides access to software, application, or toolkit that enables a software development tool that combines software documentation with generating source code. - + @@ -2860,7 +2859,7 @@ we think this should be deleted A resource that provides access to software or application that is used to enable (i) interoperability and association of data and/or (ii) pipeline of online tools. Integration and Interoperability Tool - + @@ -2873,7 +2872,7 @@ we think this should be deleted true - + @@ -2883,7 +2882,7 @@ we think this should be deleted A resource that provides legal counsel regarding contracts and agreements between an institution and various external parties. These resources may provide legal seminars along with training materials regarding intellectual property. Intellectual Property Resource - + @@ -2893,7 +2892,7 @@ we think this should be deleted Interaction Modeling Resource that provides access to software, applications, or toolkits that model or simulate interaction between biological components such as genes, proteins, cells, organs, populations. - + @@ -2903,7 +2902,7 @@ we think this should be deleted A resource that provides a network model that includes nodes and edges based on physical interactions between the entities represented by the nodes. Interaction Network - + @@ -2913,7 +2912,7 @@ we think this should be deleted Interactive Network Analysis Resource that provides access to software, application, or toolkit that analyze networks interactively with a user. - + @@ -2923,7 +2922,7 @@ we think this should be deleted Interactive Tool Resource that provides access to software, applications, or toolkits that are used to enable user input of data and display corresponding information. - + @@ -2935,7 +2934,7 @@ we think this should be deleted true - + @@ -2945,7 +2944,7 @@ we think this should be deleted Interactive Web-Based Tool Resource that provides access to software, application, or toolkit that enables hands-on resources for data management (entry, query, traversal, comparison, etc.) - + @@ -2955,7 +2954,7 @@ we think this should be deleted A resource that provides access to reports that are published journals Journal Article - + @@ -2968,7 +2967,7 @@ we think this should be deleted true - + @@ -2978,7 +2977,7 @@ we think this should be deleted Knowledge Extraction Resource that provides access to software, applications, or toolkits that recognize and report on entities and relations in text corpora. - + @@ -2989,7 +2988,7 @@ we think this should be deleted Knowledge Mining and Capturing Resource that provides access to software, applications, or toolkits that are used to extract hidden patterns from data. - + @@ -2999,7 +2998,7 @@ we think this should be deleted A resource that provides access to facts and/or information, often in the form of rules that describe the knowledge in a logically consistent manner. Knowledgebase - + @@ -3009,7 +3008,7 @@ we think this should be deleted A resource that provides items such as reagents, instruments, tissue samples or organisms for use in a laboratory. Laboratory Supply Resource - + @@ -3019,7 +3018,7 @@ we think this should be deleted Language Summarization Resource that provides access to applications, libraries, or software that creates a shortened version of text. - + @@ -3029,7 +3028,7 @@ we think this should be deleted Lexical Analysis Resource that provides access to applications, libraries, or software that converts a sequence of characters into a sequence of tokens. - + @@ -3039,7 +3038,7 @@ we think this should be deleted A resource that provides access to documented permission to do something, either from a government or under a law or regulation. License - + @@ -3052,7 +3051,7 @@ we think this should be deleted true - + @@ -3065,7 +3064,7 @@ we think this should be deleted true - + @@ -3076,7 +3075,7 @@ we think this should be deleted Light Microscope pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3086,7 +3085,7 @@ we think this should be deleted A resource which provides access to tools or functions that compute linear calculations on vector spaces. Linear Algebra Tool - + @@ -3098,7 +3097,7 @@ we think this should be deleted true - + @@ -3110,7 +3109,7 @@ we think this should be deleted MRI Scanner pending final vetting: location in hierarchy and harmonize with OBI/eagle-i - + @@ -3120,7 +3119,7 @@ we think this should be deleted Mailing List Resource that provides access to software, application, or toolkit that enable interactive Web-based tool that can be used to send information to groups. - + @@ -3130,7 +3129,7 @@ we think this should be deleted Manifold Viewer Resource that provides access to general (hyper)volume visualization tools (e.g., volume rendering). - + @@ -3143,7 +3142,7 @@ we think this should be deleted true - + @@ -3153,7 +3152,7 @@ we think this should be deleted Mapper Resource that provides access to software, application, or toolkit that enables application integration using mapping. - + @@ -3163,7 +3162,7 @@ we think this should be deleted Mass Spectra Identification Resource that provides access to software, applications, or toolkits that calculates mass spectra sequence and related data from experimental mass spectra data. - + @@ -3174,7 +3173,7 @@ we think this should be deleted Mass Spectrometer pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3184,7 +3183,7 @@ we think this should be deleted A resource that provides data from any material sample that was given to the service provider. This can also be a service which performs an experiment such as electrophysiological examination of LTP magnitude in the presence of a drug given to the service provider. Viewing this as an input/output relationship the input would involve a drug and the output would be data such as a dose response curve. Material Analysis Service - + @@ -3196,7 +3195,7 @@ we think this should be deleted BRO:0000001 Material Resource - + @@ -3206,7 +3205,7 @@ we think this should be deleted A resource that provides a service the output of which is a material object. That material object might be an instrument, a chemical, or an animal. Material Service - + @@ -3216,7 +3215,7 @@ we think this should be deleted A resource that provides material storage, maintenance and retrieval, such as the Harvard brain tissue bank. Material Storage Service - + @@ -3229,7 +3228,7 @@ we think this should be deleted true - + @@ -3239,7 +3238,7 @@ we think this should be deleted Mechanical Simulation Resource that provides access to software, applications, or toolkits that model mechanical forces. - + @@ -3249,7 +3248,7 @@ we think this should be deleted A resource that provides devices used for therapy, diagnosis or surgery. Medical Device - + @@ -3259,7 +3258,7 @@ we think this should be deleted Mesh Model Resource that provides access to software, applications, or toolkits that model or simulate biological processes using computational meshes. - + @@ -3269,7 +3268,7 @@ we think this should be deleted Meshing Resource that provides access to software, applications, or toolkits that create meshes in biological systems. - + @@ -3280,7 +3279,7 @@ we think this should be deleted Metabolism Facility pending final vetting: Refine definition - + @@ -3291,7 +3290,7 @@ we think this should be deleted Metabolomics Facility pending final vetting: Refine definition - + @@ -3301,7 +3300,7 @@ we think this should be deleted A facility or core devoted to cutting apart tissue on a very small scale such as at the level of individual cells. Micro Dissection Facility - + @@ -3312,7 +3311,7 @@ we think this should be deleted Microarray Scanner pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3323,7 +3322,7 @@ we think this should be deleted Micromanipulator pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3334,7 +3333,7 @@ we think this should be deleted Microscope pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3344,7 +3343,7 @@ we think this should be deleted A facility that provides microscopes with which to view samples or objects. Microscopy Facility - + @@ -3355,7 +3354,7 @@ we think this should be deleted Microtome pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3365,7 +3364,7 @@ we think this should be deleted A resource that provides tools or functions that aligns data with a model of the data. Model Fitting Algorithm - + @@ -3377,7 +3376,7 @@ we think this should be deleted Resource that provides access to software, applications, or toolkits that calculate solutions to models with closed form. pending final vetting: review location in hierarchy - + @@ -3387,7 +3386,7 @@ we think this should be deleted Modeling and Simulation Resource that provides access to software, applications, or toolkits that is used to model or simulate biological structures, kinetics, function, structure, random events, and genotype or phenotype in time and space. - + @@ -3400,7 +3399,7 @@ we think this should be deleted true - + @@ -3411,7 +3410,7 @@ we think this should be deleted Molecular Biology Facility pending final vetting: Refine definition - + @@ -3421,7 +3420,7 @@ we think this should be deleted Molecular Dynamics Resource that provides access to software, applications, or toolkits that involves atoms and molecules are allowed to interact for a period of time by approximations of known physics. - + @@ -3431,7 +3430,7 @@ we think this should be deleted Molecular Force Field Calculator Resource that provides access to software, applications, or toolkits that calculate molecular forces in a biomolecular system. - + @@ -3441,7 +3440,7 @@ we think this should be deleted A resource that provides data related to the measurement of interaction between molecules of any type. In version 3.2. Molecular Interaction. In version 3.2. - + @@ -3451,7 +3450,7 @@ we think this should be deleted Molecular Model Resource that provides access to software, applications, or toolkits that calculate time course of physico-chemical model that representation of a molecule or of the arrangement of molecules in a solid substance, with the purpose of visualizing some of its properties, such as the nature and relative positions of its atoms, the chemical bonds between them, the three-dimensional shape of the molecule, and how its shape can change by bending or rotation of the bonds. - + @@ -3462,7 +3461,7 @@ we think this should be deleted Resource that provides access to software, applications, or toolkits that calculate the time course of biomolecular configurations and their classification. pending final vetting: review definition - + @@ -3475,7 +3474,7 @@ we think this should be deleted true - + @@ -3488,7 +3487,7 @@ we think this should be deleted true - + @@ -3498,7 +3497,7 @@ we think this should be deleted Molecular Visualization Resource that provides access to software, applications, or toolkits that can be used to visualize a configuration of biomolecules in space and time. - + @@ -3508,7 +3507,7 @@ we think this should be deleted A resource that provides data related to molecular and cellular properties and their relationship to macroscopic parameters. Molecular and Cellular Data - + @@ -3519,7 +3518,7 @@ we think this should be deleted Monoclonal Antibody Facility pending final vetting: Refine definition - + @@ -3529,7 +3528,7 @@ we think this should be deleted A resource that provides access to tools or functions that model biological processes that involves random sampling in the algorithm. Monte Carlo Simulation - + @@ -3539,7 +3538,7 @@ we think this should be deleted Multibody Dynamics Resource that provides access to software, applications, or toolkits that can be used to calculate the time course of multibody dynamics. - + @@ -3550,7 +3549,7 @@ we think this should be deleted NMR Facility pending final vetting: Refine definition - + @@ -3561,7 +3560,7 @@ we think this should be deleted NMR Instrument pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3571,7 +3570,7 @@ we think this should be deleted Named Entity Normalization Resource that provides access to applications, libraries, or software that map the recognized entities to unambiguous references to real world entities. - + @@ -3581,7 +3580,7 @@ we think this should be deleted Named Entity Recognition Resource that provides access to applications, libraries, or software that attempts to identify and classify atomic elements in text into predefined categories such as the organizations, locations, expressions of times, quantities, and names of people. - + @@ -3592,7 +3591,7 @@ we think this should be deleted Narrative Resource Work with NIF to define blog and wiki. - + @@ -3602,7 +3601,7 @@ we think this should be deleted A resource that provides access to software, library, or application that interprets human (natural) language into a machine-interpretable form. Natural Language Processing - + @@ -3612,7 +3611,7 @@ we think this should be deleted Network Characterization Resource that provides access to tools or functions that describe a connectivity between components at the genomic, molecular, cellular, tissue level, or population levels. - + @@ -3625,7 +3624,7 @@ we think this should be deleted true - + @@ -3635,7 +3634,7 @@ we think this should be deleted Network Interaction Model Resource that provides access to software, applications, or toolkits that can be used model a molecular, cellular, organ, or population network. - + @@ -3652,7 +3651,7 @@ we think this should be deleted e.g. Sage Bionetworks will be publishing exactly these types of models. - + @@ -3662,7 +3661,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides access to or support for a system of interconnected computers able to share information. Network and Communication - + @@ -3675,7 +3674,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.true - + @@ -3686,7 +3685,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Neurological Facility pending final vetting: Refine definition - + @@ -3696,7 +3695,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Neuromuscular Model Resource that provides access to software, applications, or toolkits that can be used to model combined biomechanical and neurological system. - + @@ -3706,7 +3705,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.News Resource that provides news and RSS feed resources - + @@ -3717,7 +3716,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Next generation of High throughput DNA sequencer (http://en.wikipedia.org/wiki/DNA_sequencing) pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3730,7 +3729,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.true - + @@ -3743,7 +3742,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.true - + @@ -3753,7 +3752,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Numerical Calculation of Electrostatic Potential Resource that provides access to software, applications, or toolkits that can be used to calculate the electrostatic potential of biomolecular configurations. - + @@ -3763,7 +3762,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Numerical Integrator Resource that provides access to tools or functions that calculate the numerical value of a definite integral. - + @@ -3775,7 +3774,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.true - + @@ -3785,7 +3784,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Numerical Method Resource that provides access to methods of numerical analysis or computational tools (ala, GAMS: http://gams.nist.gov/). - + @@ -3798,7 +3797,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.true - + @@ -3808,7 +3807,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Numerical Model Resource that provides access to software, applications, or toolkits that generate solutions from a numerical model. - + @@ -3819,7 +3818,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Nutrition Facility pending final vetting: Refine definition - + @@ -3829,7 +3828,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides access to a database that represents information in the form of objects. Object Database - + @@ -3839,7 +3838,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Online Course Resource that provides online training and educational resources. - + @@ -3849,7 +3848,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Online Support Resource that provides access to software, application, or toolkit that enable help via internet accessible material. - + @@ -3859,7 +3858,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides access to a set of concepts within a domain and the relationships between those concepts, used to reason about the objects within that domain. Ontology - + @@ -3869,7 +3868,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Ontology Development Resource that provides access to ontology and development management tool that allows a user to develop a set of terms, and the hierarchial relationship between them as well as metadata about the terms. - + @@ -3879,7 +3878,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Ontology Development and Management Resource that provides access to software development tool that can be used to build a set of terms and specify the relationship between the terms. - + @@ -3889,7 +3888,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Ontology Diff and Alignment Resource that provides access to an ontology and development management tool that identifies differences between two ontologies. - + @@ -3899,7 +3898,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Ontology Visualization Resource that provides access to a ontology development and management tool that is used to generate an image of the ontology. - + @@ -3909,7 +3908,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides access to a tool or function that locates the extremum (usually minimum) of a cost function subject to constraints., Optimizer - + @@ -3920,7 +3919,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Oscillograph pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3931,7 +3930,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Oscilloscope pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3941,7 +3940,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.Outlier Detection and Removal Resource that provides access to software, applications, or toolkits that perform quality assurance on data to detect and/or remove outliers. - + @@ -3951,7 +3950,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides general education to the public. Outreach Program - + @@ -3962,7 +3961,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.PCR Facility pending final vetting: Refine definition - + @@ -3973,7 +3972,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.PCR Instrument pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -3983,7 +3982,7 @@ e.g. Sage Bionetworks will be publishing exactly these types of models.A resource that provides access to a tool or function that generates the solution of a partial differential equation subject to appropriate parameters and initial or boundary conditions. PDE Solver - + @@ -3996,7 +3995,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ PET Scanner pending final vetting: location in hierarchy and harmonize with OBI/eagle-i - + @@ -4006,7 +4005,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ An unpublished document, which may also be submitted to a publisher for publication. Paper - + @@ -4016,7 +4015,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Parsing Resource that provides access to applications, libraries, or software that analyze text to detect language constructs or tokens such as noun phrases and verbs. - + @@ -4026,7 +4025,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Partial Parsing Resource that provides access to applications, libraries, or software that parse part of a text or corpus. - + @@ -4039,7 +4038,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4049,7 +4048,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to documents describing the exclusive right granted by a government to an inventor to manufacture, use, or sell an invention for a certain number of years. Patent - + @@ -4059,7 +4058,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides the analysis of biological samples. An example is genotyping transgenic mice. Pathology Laboratory Screening - + @@ -4069,7 +4068,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to tools or functions that derive reduced significant information about experimental or synthetic data. Pattern Inference Algorithm - + @@ -4079,7 +4078,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pattern Recognition Resource that provides access to tools for the representation, modeling, analysis and visualization of biological patterns out of data. - + @@ -4089,7 +4088,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pattern and Motif Inference Resource that provides access to software, applications, or toolkits that generate patterns or motifs based on applying logics and statistics to observations/hypothesis. - + @@ -4101,20 +4100,20 @@ radionuclide (tracer), which is introduced into the body on a biologically activ BRO:0000002 I spent some time thinking about the distinction between People Resources and Services Resources. Then I spent some time thinking of what would be subclasses of people. Below is the list I came up with. However, it bares striking similarity to what we had envisioned for Related Activity or Area of Research. Looking over at NIF, they defined People Resource as "A resource that provides access to individual people based, for example, on expertise or affiliation" and do not have any child nodes. I think I've come around to the opinion that we should either adopt NIF's approach, or change from having the top level People Resource to Consulting Resource as a child of Service Resource. (then still tbd whether to have children of that- I think I'd vote for not.) Note that we're already not in complete alignment at the top level- NIF has "Job Resource". I look forward to discussion with the group. -- grant prep  -- business development    +- grant prep +- business development - industry partnership -- toxicology  -- funding discovery  -- legal counsel  -- intellectual property  -- IRB  -- community outreach  -- finance  -- regulatory compliance  -- minority health  -- study design    -- clinical trials   +- toxicology +- funding discovery +- legal counsel +- intellectual property +- IRB +- community outreach +- finance +- regulatory compliance +- minority health +- study design +- clinical trials - basic research - Informatics - Biostatistics @@ -4122,7 +4121,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - development People Resource - + @@ -4132,7 +4131,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a communication between an agent and one or more specific recipients., Personal Communication - + @@ -4143,7 +4142,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pharmacokinetics Pharmacodynamics Expertise pending final vetting: refine definition - + @@ -4154,7 +4153,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to applications, libraries, or software that perform inference and information retrieval on biological phenotype data. pending final vetting: review location in hierarchy - + @@ -4164,7 +4163,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides data related to any kind of measurement designed to describe an observable characteristic or trait. Phenotypic Measurement - + @@ -4174,7 +4173,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A facility or core devoted to the act or practice of opening a vein by incision or puncture to remove blood. Phlebotomy Facility - + @@ -4184,7 +4183,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Physico-Chemical Model Resource that provides access to software, applications, or toolkits that calculate solutions to physiological processes that involve chemical kinetics, compartments, or stochastic interactions. - + @@ -4195,7 +4194,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Physiology Facility pending final vetting: Refine definition - + @@ -4205,7 +4204,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Physioloigcal Model Resource that provides access to software, applications, or toolkits that can be used model physiology. - + @@ -4215,7 +4214,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pipeline Manager Resource that provides access to software, applications, or toolkits that manage software pipelines - + @@ -4228,7 +4227,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Portal pending final vetting: review NIF hierarchy for source of children terms. - + @@ -4241,7 +4240,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4252,7 +4251,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Power Conditioning Unit pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -4262,7 +4261,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pre-Processing Resource that provides access to software, applications, or toolkits that perform image pre-processing routines that are required as preliminary steps before standard image processing, analysis and visualization take place. - + @@ -4272,7 +4271,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Prediction of Side-Chain Conformations Resource that provides access to software, applications, or toolkits that can be used to calculate the estimate of side chains of conformations in biomolecular configurations. - + @@ -4282,7 +4281,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Pressure Regulator pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -4292,7 +4291,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A funding resource where money is supplied by a non governmental organization, foundation, or company. Private Funding Resource - + @@ -4302,7 +4301,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Processing Pipeline Resource that provides access to software, applications, or toolkits that enable execution processing. - + @@ -4313,7 +4312,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Programmatic Access pending final vetting: propose to deprecate, but replacement term needed since this term is used in annotation - + @@ -4323,7 +4322,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides a description of the interaction network of proteins. Protein-Protein Interaction - + @@ -4333,7 +4332,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides data related to the presence and abundance of proteins from a cell or tissue sample. Protein Expression - + @@ -4343,7 +4342,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Protein Interaction Modeling Resource that provides access to software, applications, or toolkits that can be used to model protein interactions. - + @@ -4353,7 +4352,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Protein Model Resource that provides access to software, applications, or toolkits that can be used to specifically model protein structure and function. - + @@ -4364,7 +4363,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Proteomics Facility pending final vetting: Refine definition - + @@ -4375,7 +4374,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Protocol Development Expertise pending final vetting: refine definition - + @@ -4388,7 +4387,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4401,7 +4400,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4412,7 +4411,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Psychometrics Expertise pending final vetting: refine definition - + @@ -4425,7 +4424,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4435,7 +4434,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to structured data that is formatted according to the Resource Description Framework, a language for representing information about resources in the World Wide Web. RDF Data - + @@ -4445,7 +4444,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ RNA Model Resource that provides access to software, applications, or toolkits that can be used to specifically model RNA structure and function., - + @@ -4456,7 +4455,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Rack pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -4467,7 +4466,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Radioisotopes Facility pending final vetting: Refine definition - + @@ -4477,7 +4476,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Random Number Simulation Resource that provides access to software, applications, or toolkits that can be used perform simulations using sampling and re-sampling methods for random events. - + @@ -4487,7 +4486,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that manufactures a product that could have a role as reagent. Examples include producing antibodies to a particular antigen (Charles River custom antibody service) or designing drugs which fit a receptor. Reagent Manufacture - + @@ -4497,7 +4496,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A material resource that provides access to reagents, such as antibodies or drugs. Included in this definition are sites designed to work with individual service providers of reagents such as ExactAntigen who do not sell antibodies directly, but provide a catalog with pricing information for most commercial and noncommercial antibody providers. Note, reagents may be of organismal origin or not, but must be classified as macromolecules or molecules. Reagent Resource - + @@ -4507,7 +4506,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Registration Resource that provides access to software, applications, or toolkits that performs methods for co-registration, alignment and warping of imaging and hyper-imaging data. - + @@ -4517,7 +4516,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Regularization and Smoothing Resource that provides access to software, applications, or toolkits that smooths time series data. - + @@ -4527,7 +4526,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides guidance related to ethical or legal matters concerning scientific research. These resources provide both information regarding ethical/legal research matters as well as methods for developing, applying, assessing and reviewing regulations (i.e. compliance documents, procedures, consent forms, etc). These resources can include both materials and documentation along with expertise in the form of personnel. Regulatory Compliance Resource - + @@ -4537,7 +4536,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides guidelines for complying with federal, state, and local regulations (e.g. research integrity office, research policy office, etc). The resource can provide seminars, documents, and other items regarding regulations. Regulatory Policy Resource - + @@ -4547,7 +4546,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ PML Resource that provides access to tools or functions that generate network maps of biological signaling or regulatory networks based on applying logic and statistics to observations/hypothesis. Regulatory Signaling Network Reconstruction - + @@ -4557,7 +4556,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a database that comprises a normalized data set constructed according to a specific entity-relation data model. Relational Database - + @@ -4567,7 +4566,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to documents describing an account, event, situation, or the like, usually as the result of observation, inquiry, etc. Report - + @@ -4578,7 +4577,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Research Animals Facility pending final vetting: Refine definition - + @@ -4591,7 +4590,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4600,7 +4599,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ An entity that provides access (either in the open community or within an organization) to material, intellectual, financial, technological, or electronic means of carrying out research and development. Resource - + @@ -4610,7 +4609,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource Integration Component Resource that provides access to software, application, or toolkit that enable integration of diverse resources. - + @@ -4621,7 +4620,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Robotic Arrayer pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -4631,7 +4630,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a tool or function that finds a value x such that f(x) = 0, for a given function f. Such an x is called a root of the function f. Root Finder - + @@ -4644,7 +4643,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4657,7 +4656,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4667,7 +4666,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that search, sort, or index on binary or textual formatted data. Searching Sorting and Indexing - + @@ -4677,7 +4676,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that classify sub-regions of images. Segmentation - + @@ -4690,7 +4689,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4700,7 +4699,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides data that is partially structured. Semi-Structured Knowledge Resource - + @@ -4710,7 +4709,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides presentations from experts within their field. Seminar Series - + @@ -4720,7 +4719,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to applications, libraries, or software that divide sentences into components or fragments. Sentence Splitting - + @@ -4730,7 +4729,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that compare two or more genomic sequences and provides summary information. Sequence Alignment - + @@ -4740,7 +4739,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to tools or functions that provide information beyond biological sequence, e.g., function. Sequence Annotation - + @@ -4750,7 +4749,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to tools or functions that perform similarity searching involving biological sequences. Sequence Similarity Searching - + @@ -4760,7 +4759,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to molecular sequence viewers. Sequence Visualization - + @@ -4773,7 +4772,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4784,7 +4783,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As per alignment with NIF resource type hierarchy. Service Resource - + @@ -4794,7 +4793,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to tools representation, modeling, analysis and visualization of biological shape out of data. Shape Analysis - + @@ -4805,7 +4804,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that analysis multi-dimensional spatio-temporal data. Signal Processing - + @@ -4816,7 +4815,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that generate network maps of biological signaling networks based on applying logic and statistics to observations/hypothesis. Signaling Network Reconstruction - + @@ -4826,7 +4825,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that methods for removing of segments from images, which have no valuable information about the biological object. For example, removing non-brain tissue from whole-brain MRI scans, for the purpose of doing quantitative evaluations of time or space changing brain anatomy. Skull Stripping - + @@ -4837,7 +4836,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access usually through repositories or the Internet to computer executables, libraries, plugins, or source code. Software - + @@ -4847,7 +4846,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides the entire environment (applications, servers, network) that provides comprehensive facilities to computer programmers for software development. An SDE typically includes an integrated development environment (IDE, comprising source code editor, compiler, build automation, debugger), requirement management tools, design modeling tools, documentation generation tools, code analysis tools, and so on. Software Development Environment - + @@ -4857,7 +4856,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, application, or toolkit that enable interactive tools for generating a computer program. Software Development Resource - + @@ -4867,7 +4866,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, application, or toolkit that enable generic tools for software development, engineering and deployment. Software Development Tool - + @@ -4882,7 +4881,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4895,7 +4894,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4905,7 +4904,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, application, or toolkit that enables professional software engineering processes. Software Engineering Tool - + @@ -4915,7 +4914,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to information on how to implement and use a computer program. Software Technology Protocol - + @@ -4928,7 +4927,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - + @@ -4941,7 +4940,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4951,7 +4950,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, application, or toolkit that enable software source control methods. Source Control - + @@ -4961,7 +4960,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that perform spatial and frequency-type data transformations. Spectral Transform - + @@ -4974,7 +4973,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -4984,7 +4983,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a generally agreed upon set of rules for representation. Standard Specification - + @@ -4994,7 +4993,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A funding resource that is provided by a state. State Funding Resource - + @@ -5004,7 +5003,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to tools or functions that calculate basic methods of statistics and biometrics. Statistical Algorithm - + @@ -5014,7 +5013,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to software, applications, or toolkits for basic statistical modeling and analysis. Statistical Analysis - + @@ -5024,7 +5023,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to self-contained tools, resources and packages for statistical modeling and data analysis (e.g., R, SOCR, SAS, SPSS, SYSTAT, etc.). Statistical Package - + @@ -5034,7 +5033,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that performs statistical tests on text corpora. Statistical Text Analysis - + @@ -5044,7 +5043,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A facility that provides resources for the development and growth of self-renewing cells that are capable of differentiation into a diverse range of specialized cells. Stem Cell Therapy Facility - + @@ -5055,7 +5054,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Stimulator pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -5068,7 +5067,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5078,7 +5077,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that can be used to model based on a coordinate-based mathematical description of a collection of biological structures. Structural Model - + @@ -5088,7 +5087,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that can be used to classify protein shape and parameters. Structure-Based Protein Classification - + @@ -5101,7 +5100,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5111,7 +5110,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to an electronic document having and manifesting a clearly defined structure or organization that allows it to be executed. Structured File - + @@ -5121,7 +5120,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to collection of data records arranged according to some semantic framework. The semantic framework may be minimally expressive - such as a simple controlled vocabulary - or highly expressive such as a formally structured ontology. Such resources may include only a representation of universal/classes/categories or may be linked to individual instance data typed according to a set of asserted classes (i.e., a knowledgebase). Structured Knowledge Resource - + @@ -5134,7 +5133,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5147,7 +5146,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5157,7 +5156,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to methods of analysis and modeling that have closed-form analytical mathematical representations. Symbolic and Analytic Model - + @@ -5169,7 +5168,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Technical Support pending final vetting: refine definition - + @@ -5180,7 +5179,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Temperature Control Unit pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -5190,7 +5189,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to a software development tool to perform quality assurance of software. Testing Tools - + @@ -5201,7 +5200,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that derives information from free text. Text Mining - + @@ -5211,7 +5210,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a document created to summarize research findings associated with the completion of an academic degree. Thesis - + @@ -5221,7 +5220,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides image data consisting of length, width and depth. Three D Image - + @@ -5234,7 +5233,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5244,7 +5243,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that includes methods for analyzing time series data in order to extract meaningful statistics and other characteristics of the data. Time Series Analysis - + @@ -5254,7 +5253,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A facility that provides resources relating to tissues used in biomedical research. Tissue Organ Facility - + @@ -5267,7 +5266,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5278,7 +5277,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Toxicology Expertise pending final vetting: refine definition - + @@ -5289,7 +5288,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As per alignment with NIF resource type hierarchy. Training Resource - + @@ -5300,7 +5299,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Training Service pending final vetting: review location in hierarchy - + @@ -5310,7 +5309,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ An educational resource that is interactive and teaches by example. Tutorial - + @@ -5323,7 +5322,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5333,7 +5332,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides image data consisting of length and width, but no depth. Two D Image - + @@ -5346,7 +5345,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5357,7 +5356,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Suggested child terms: audio track, slide, and video per NIF. Work with NIF to generate definitions. Unstructured Knowledge Resource - + @@ -5370,7 +5369,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5380,7 +5379,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides a system for the management of multiple revisions of the same unit of information. It is most commonly used in engineering and software development to manage ongoing development of digital documents like application source code, art resources such as blueprints or electronic models, and other projects that may be worked on by a team of people. Version Source Control System - + @@ -5391,7 +5390,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Vibration Isolation Table pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -5402,7 +5401,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Vibrotome pending final vetting: work with eagle-i to define terms since out of scope of BRO - + @@ -5412,7 +5411,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to tools for graphical, interactive, multimodal and multidimensional data and result visualization. Visualization - + @@ -5423,7 +5422,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Volume Model Scene Data pending final vetting: provide definition - + @@ -5433,7 +5432,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that can be used model a system using or described by wavelets. Wavelet Model - + @@ -5443,7 +5442,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that performs multi-dimensional wavelet transform. Wavelet Transform - + @@ -5453,7 +5452,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to an ontology development and management tool that can be accessed via the Web. Web Access - + @@ -5463,7 +5462,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resources that are disseminated on the Internet via HTTP, FTP and other web protocols. Web Posting - + @@ -5476,7 +5475,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5487,7 +5486,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, application, or toolkit that can develop access to a connected group of pages on the World Wide Web regarded as a single entity, usually maintained by one person or organization and devoted to a single topic or several closely related topics. Website - + @@ -5497,7 +5496,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides space for and access to a web server and content. Website Hosting - + @@ -5507,7 +5506,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A publication that is an authoritative report or guide that often addresses issues and how to solve them. White Paper - + @@ -5518,7 +5517,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource that provides access to software, applications, or toolkits that can be used to build or manage frameworks that provides sets of interoperable software tools. Workbench - + @@ -5529,7 +5528,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ X-Ray Crystallography Facility pending final vetting: Refine definition - + @@ -5539,7 +5538,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to structured data that is in XML, a self-descriptive format to store and transport data. XML Data - + @@ -5549,7 +5548,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ A resource that provides access to a database that stores XML. XML Database - + @@ -5562,7 +5561,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ true - + @@ -5571,7 +5570,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Area of Research Area of research that may be related to a BRO:Resource. - + @@ -5581,7 +5580,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Behavioral_science Behavioral Science - + @@ -5591,7 +5590,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Bioinformatics Bioinformatics - + @@ -5601,7 +5600,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Biostatistics Biostatistics - + @@ -5611,7 +5610,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Clinical Studies or resources that help investigators do clinical studies or trials, including, epidemiology (http://en.wikipedia.org/wiki/Epidemiology), outcome development, physiological human studies, interventional trials, etc - + @@ -5621,7 +5620,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Computational_biology Computational Biology - + @@ -5631,7 +5630,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Former subclasses of area:Area_of_Research that have been deprecated and their usage is not recommended. true - + @@ -5641,7 +5640,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Epidemiolgy Epidemiology - + @@ -5651,7 +5650,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Genomics The study of all the genes of a cell, tissue, or organism at the DNA (genotype) or mRNA (transcriptome) levels. - + @@ -5661,7 +5660,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Metabolomics Metabolomics - + @@ -5671,7 +5670,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Nursing Nursing - + @@ -5681,7 +5680,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Outcomes_research Outcomes Research - + @@ -5691,7 +5690,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Pathology Pathology - + @@ -5701,7 +5700,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Pediatrics Pediatrics - + @@ -5711,7 +5710,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Pharmacokinetics and http://en.wikipedia.org/wiki/Pharmacodynamics Pharmacokinetics Pharmacodynamics - + @@ -5721,7 +5720,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Physiology Physiology - + @@ -5731,7 +5730,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Preclinical The stages of biomedical research which take place in model organisms and cell lines, prior to first-in-human application of a diagnostic or therapeutic intervention. - + @@ -5741,7 +5740,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Proteomics The large-scale study of proteins - + @@ -5751,7 +5750,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ As defined in http://en.wikipedia.org/wiki/Psychometrics Psychometrics - + @@ -5761,7 +5760,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Framework solutions that enable scientists to work smarter and ultimately increase the number of scientific discoveries made, as well as decrease the time to publish results. (http://en.wikipedia.org/wiki/Information_technology) Research IT - + @@ -5771,7 +5770,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Toxicology defined in http://en.wikipedia.org/wiki/Toxicology - + @@ -5780,7 +5779,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Biositemaps Information Model hasDbXref0000000 - + @@ -5789,7 +5788,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Resource Description - + @@ -5798,16 +5797,16 @@ radionuclide (tracer), which is introduced into the body on a biologically activ Version Information - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -6273,7 +6272,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - + @@ -6281,7 +6280,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - + @@ -6289,7 +6288,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - + @@ -6297,7 +6296,7 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - + @@ -6305,10 +6304,10 @@ radionuclide (tracer), which is introduced into the body on a biologically activ - - - + \ No newline at end of file diff --git a/test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl b/test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl index 27a0dcb01..317141372 100644 --- a/test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl +++ b/test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl @@ -763,10 +763,10 @@ http://creativecommons.org/licenses/by/3.0/ - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -900,31 +900,31 @@ - + - + - + - + - + @@ -932,16 +932,16 @@ - + - - - + - + - + - + - + - - - + @@ -1002,7 +1002,7 @@ Liquid substances produced by living organisms to fulfill specific functions or excreted as waste. - + @@ -1013,7 +1013,7 @@ Liquid components of living organisms. - + @@ -1094,7 +1094,7 @@ The serous fluid of ascites, the accumulation of fluids in the peritoneal cavity. - + @@ -1147,7 +1147,7 @@ Fluid accumulation within the pericardium. Serous effusions are associated with pericardial diseases. Hemopericardium is associated with trauma. Lipid-containing effusion (chylopericardium) results from leakage of thorasic duct. Severe cases can lead to cardiac tamponade. - + @@ -1486,7 +1486,7 @@ Presence of fluid in the pleural cavity resulting from excessive transudation or exudation from the pleural surfaces. It is a sign of disease and not a diagnosis in itself. - + @@ -1496,7 +1496,7 @@ A biomolecule is any organic molecule that is produced by a living organism, including large polymeric molecules such as proteins, polysaccharides, and nucleic acids as well as small molecules such as primary metabolites, secondary metabolites, and natural products. - + @@ -1507,7 +1507,7 @@ A bacterial toxin is a type of toxin that is generated by bacteria. - + @@ -1517,7 +1517,7 @@ >cholera endotoxin - + @@ -1528,7 +1528,7 @@ Chemical substances having a specific regulatory effect on the activity of a certain organ or organs. The term was originally applied to substances secreted by various endocrine glands and transported in the bloodstream to the target organs. It is sometimes extended to include those substances that are not produced by the endocrine glands but that have similar effects. - + @@ -1540,7 +1540,7 @@ Hormones secreted from Adrenal cortex. - + @@ -1549,7 +1549,7 @@ glucocorticoids - + @@ -1561,7 +1561,7 @@ Hormones secreted from Pancreas - + @@ -1572,7 +1572,7 @@ A pancreatic polypeptide of about 110 amino acids, depending on the species, that is the precursor of insulin. Proinsulin, produced by the pancreatic beta cells, is comprised sequentially of the N-terminal B-chain, the proteolytically removable connecting C-peptide, and the C-terminal A-chain. It also contains three disulfide bonds, two between A-chain and B-chain. After cleavage at two locations, insulin and C-peptide are the secreted products. Intact proinsulin with low bioactivity also is secreted in small amounts. - + @@ -1589,7 +1589,7 @@ A 51-amino acid pancreatic hormone that plays a major role in the regulation of glucose metabolism, directly by suppressing endogenous glucose production (glycogenolysis; gluconeogenesis) and indirectly by suppressing glucagon secretion and lipolysis. Native insulin is a globular protein comprised of a zinc-coordinated hexamer. Each insulin monomer containing two chains, A (21 residues) and B (30 residues), linked by two disulfide bonds. Insulin is used as a drug to control insulin-dependent diabetes mellitus (Diabetes mellitus, type 1) - + @@ -1600,7 +1600,7 @@ Linear polypeptides that are synthesized on ribosomes and may be further modified, crosslinked, cleaved, or assembled into complex proteins with several subunits. The specific sequence of amino acids determines the shape the polypeptide will take, during protein folding, and the function of the protein. - + @@ -1675,7 +1675,7 @@ The androgen receptor gene is more than 90 kb long and codes for a protein that has 3 major functional domains: the N-terminal domain, DNA-binding domain, and androgen-binding domain. The protein functions as a steroid-hormone activated transcription factor. Upon binding the hormone ligand, the receptor dissociates from accessory proteins, translocates into the nucleus, dimerizes, and then stimulates transcription of androgen responsive genes. This gene contains 2 polymorphic trinucleotide repeat segments that encode polyglutamine and polyglycine tracts in the N-terminal transactivation domain of its protein. Expansion of the polyglutamine tract causes spinal bulbar muscular atrophy (Kennedy disease). Mutations in this gene are also associated with complete androgen insensitivity (CAIS). Two alternatively spliced variants encoding distinct isoforms have been described. - + @@ -1813,7 +1813,7 @@ This gene encodes a nuclear phosphoprotein that plays a role in maintaining genomic stability, and it also acts as a tumor suppressor. The encoded protein combines with other tumor suppressors, DNA damage sensors, and signal transducers to form a large multi-subunit protein complex known as the BRCA1-associated genome surveillance complex (BASC). This gene product associates with RNA polymerase II, and through the C-terminal domain, also interacts with histone deacetylase complexes. This protein thus plays a role in transcription, DNA repair of double-stranded breaks, and recombination. Mutations in this gene are responsible for approximately 40% of inherited breast cancers and more than 80% of inherited breast and ovarian cancers. Alternative splicing plays a role in modulating the subcellular localization and physiological function of this gene. Many alternatively spliced transcript variants, some of which are disease-associated mutations, have been described for this gene, but the full-length natures of only some of these variants has been described. A related pseudogene, which is also located on chromosome 17, has been identified. - + @@ -1853,7 +1853,7 @@ This gene encodes a high affinity receptor for the peptide hormone calcitonin and belongs to a subfamily of seven transmembrane-spanning G protein-coupled receptors. The encoded protein is involved in maintaining calcium homeostasis and in regulating osteoclast-mediated bone resorption. Polymorphisms in this gene have been associated with variations in bone mineral density and onset of osteoporosis. Alternate splicing results in multiple transcript variants. - + @@ -1910,7 +1910,7 @@ The protein encoded by this gene belongs to the highly conserved cyclin family, whose members are characterized by a dramatic periodicity in protein abundance throughout the cell cycle. Cyclins function as regulators of CDK kinases. Different cyclins exhibit distinct expression and degradation patterns which contribute to the temporal coordination of each mitotic event. This cyclin forms a complex with and functions as a regulatory subunit of CDK4 or CDK6, whose activity is required for cell cycle G1/S transition. This protein has been shown to interact with tumor suppressor protein Rb and the expression of this gene is regulated positively by Rb. Mutations, amplification and overexpression of this gene, which alters cell cycle progression, are observed frequently in a variety of tumors and may contribute to tumorigenesis. - + @@ -2012,7 +2012,7 @@ The protein encoded by this gene is a cell-surface glycoprotein involved in cell-cell interactions, cell adhesion and migration. It is a receptor for hyaluronic acid (HA) and can also interact with other ligands, such as osteopontin, collagens, and matrix metalloproteinases (MMPs). This protein participates in a wide variety of cellular functions including lymphocyte activation, recirculation and homing, hematopoiesis, and tumor metastasis. Transcripts for this gene undergo complex alternative splicing that results in many functionally distinct isoforms, however, the full length nature of some of these variants has not been determined. Alternative splicing is the basis for the structural and functional diversity of this protein, and may be related to tumor metastasis. - + @@ -2027,7 +2027,7 @@ - + @@ -2081,7 +2081,7 @@ - + @@ -2267,7 +2267,7 @@ This gene encodes a muscle-specific class III intermediate filament. Homopolymers of this protein form a stable intracytoplasmic filamentous network connecting myofibrils to each other and to the plasma membrane. Mutations in this gene are associated with desmin-related myopathy, a familial cardiac and skeletal myopathy (CSM), and with distal myopathies. - + @@ -2302,7 +2302,7 @@ Epidermal growth factor has a profound effect on the differentiation of specific cells in vivo and is a potent mitogenic factor for a variety of cultured cells of both ectodermal and mesodermal origin. The EGF precursor is believed to exist as a membrane-bound molecule which is proteolytically cleaved to generate the 53-amino acid peptide hormone that stimulates cells to divide. - + @@ -2413,7 +2413,7 @@ The protein encoded by this gene is a transmembrane glycoprotein that is a member of the protein kinase superfamily. This protein is a receptor for members of the epidermal growth factor family. EGFR is a cell surface protein that binds to epidermal growth factor. Binding of the protein to a ligand induces receptor dimerization and tyrosine autophosphorylation and leads to cell proliferation. Mutations in this gene are associated with lung cancer. - + @@ -2730,7 +2730,7 @@ This gene encodes a carcinoma-associated antigen and is a member of a family that includes at least two type I membrane proteins. This antigen is expressed on most normal epithelial cells and gastrointestinal carcinomas and functions as a homotypic calcium-independent cell adhesion molecule. The antigen is being used as a target for immunotherapy treatment of human carcinomas. Mutations in this gene result in congenital tufting enteropathy. - + @@ -3080,7 +3080,7 @@ This gene encodes a member of the epidermal growth factor (EGF) receptor family of receptor tyrosine kinases. This protein has no ligand binding domain of its own and therefore cannot bind growth factors. However, it does bind tightly to other ligand-bound EGF receptor family members to form a heterodimer, stabilizing ligand binding and enhancing kinase-mediated activation of downstream signalling pathways, such as those involving mitogen-activated protein kinase and phosphatidylinositol-3 kinase. Allelic variations at amino acid positions 654 and 655 of isoform a (positions 624 and 625 of isoform b) have been reported, with the most common allele, Ile654/Ile655, shown here. Amplification and/or overexpression of this gene has been reported in numerous cancers, including breast and ovarian tumors. Alternative splicing results in several additional transcript variants, some encoding different isoforms and others that have not been fully characterized. - + @@ -3180,7 +3180,7 @@ This gene encodes a member of the epidermal growth factor receptor (EGFR) family of receptor tyrosine kinases. This membrane-bound protein has a neuregulin binding domain but not an active kinase domain. It therefore can bind this ligand but not convey the signal into the cell through protein phosphorylation. However, it does form heterodimers with other EGF receptor family members which do have kinase activity. Heterodimerization leads to the activation of pathways which lead to cell proliferation or differentiation. Amplification of this gene and/or overexpression of its protein have been reported in numerous cancers, including prostate, bladder, and breast tumors. Alternate transcriptional splice variants encoding different isoforms have been characterized. One isoform lacks the intermembrane region and is secreted outside the cell. This form acts to modulate the activity of the membrane-bound form. Additional splice variants have also been reported, but they have not been thoroughly characterized. - + @@ -3251,7 +3251,7 @@ This gene is a member of the Tyr protein kinase family and the epidermal growth factor receptor subfamily. It encodes a single-pass type I membrane protein with multiple cysteine rich domains, a transmembrane domain, a tyrosine kinase domain, a phosphotidylinositol-3 kinase binding site and a PDZ domain binding motif. The protein binds to and is activated by neuregulins and other factors and induces a variety of cellular responses including mitogenesis and differentiation. Multiple proteolytic events allow for the release of a cytoplasmic fragment and an extracellular fragment. Mutations in this gene have been associated with cancer. Alternatively spliced variants which encode different protein isoforms have been described; however, not all variants have been fully characterized. - + @@ -3336,7 +3336,7 @@ This gene encodes an estrogen receptor, a ligand-activated transcription factor composed of several domains important for hormone binding, DNA binding, and activation of transcription. The protein localizes to the nucleus where it may form a homodimer or a heterodimer with estrogen receptor 2. Estrogen and its receptors are essential for sexual development and reproductive function, but also play a role in other tissues such as bone. Estrogen receptors are also involved in pathological processes including breast cancer, endometrial cancer, and osteoporosis. Alternative splicing results in several transcript variants, which differ in their 5' UTRs and use different promoters. - + @@ -3775,7 +3775,7 @@ Estrogen receptor is a ligand-activated transcription factor composed of several domains important for hormone binding, DNA binding, and activation of transcription. The protein localizes to the nucleus where it may form a homodimer or a heterodimer with estrogen receptor 2. Estrogen and its receptors are essential for sexual development and reproductive function, but also play a role in other tissues such as bone. Estrogen receptors are also involved in pathological processes including breast cancer, endometrial cancer, and osteoporosis. - + @@ -3871,7 +3871,7 @@ This gene encodes a member of the F-box protein family which is characterized by an approximately 40 amino acid motif, the F-box. The F-box proteins constitute one of the four subunits of ubiquitin protein ligase complex called SCFs (SKP1-cullin-F-box), which function in phosphorylation-dependent ubiquitination. The F-box proteins are divided into 3 classes: Fbws containing WD-40 domains, Fbls containing leucine-rich repeats, and Fbxs containing either different protein-protein interaction modules or no recognizable motifs. The protein encoded by this gene was previously referred to as FBX30, and belongs to the Fbws class; in addition to an F-box, this protein contains 7 tandem WD40 repeats. This protein binds directly to cyclin E and probably targets cyclin E for ubiquitin-mediated degradation. Mutations in this gene are detected in ovarian and breast cancer cell lines, implicating the gene's potential role in the pathogenesis of human cancers. Three transcript variants encoding three different isoforms have been found for this gene. - + @@ -3999,7 +3999,7 @@ The protein encoded by this gene is a member of the fibroblast growth factor receptor (FGFR) family, where amino acid sequence is highly conserved between members and throughout evolution. FGFR family members differ from one another in their ligand affinities and tissue distribution. A full-length representative protein consists of an extracellular region, composed of three immunoglobulin-like domains, a single hydrophobic membrane-spanning segment and a cytoplasmic tyrosine kinase domain. The extracellular portion of the protein interacts with fibroblast growth factors, setting in motion a cascade of downstream signals, ultimately influencing mitogenesis and differentiation. This particular family member binds both acidic and basic fibroblast growth factors and is involved in limb induction. Mutations in this gene have been associated with Pfeiffer syndrome, Jackson-Weiss syndrome, Antley-Bixler syndrome, osteoglophonic dysplasia, and autosomal dominant Kallmann syndrome 2. Chromosomal aberrations involving this gene are associated with stem cell myeloproliferative disorder and stem cell leukemia lymphoma syndrome. Alternatively spliced variants which encode different protein isoforms have been described; however, not all variants have been fully characterized. - + @@ -4115,7 +4115,7 @@ The protein encoded by this gene is a member of the fibroblast growth factor receptor family, where amino acid sequence is highly conserved between members and throughout evolution. FGFR family members differ from one another in their ligand affinities and tissue distribution. A full-length representative protein consists of an extracellular region, composed of three immunoglobulin-like domains, a single hydrophobic membrane-spanning segment and a cytoplasmic tyrosine kinase domain. The extracellular portion of the protein interacts with fibroblast growth factors, setting in motion a cascade of downstream signals, ultimately influencing mitogenesis and differentiation. This particular family member is a high-affinity receptor for acidic, basic and/or keratinocyte growth factor, depending on the isoform. Mutations in this gene are associated with Crouzon syndrome, Pfeiffer syndrome, Craniosynostosis, Apert syndrome, Jackson-Weiss syndrome, Beare-Stevenson cutis gyrata syndrome, Saethre-Chotzen syndrome, and syndromic craniosynostosis. Multiple alternatively spliced transcript variants encoding different isoforms have been noted for this gene. - + @@ -4152,7 +4152,7 @@ The fibroblast growth factor receptors consist of an extracellular ligand domain composed of three immunoglobulin-like domains, a single transmembrane helix domain, and an intracellular domain with tyrosine kinase activity. These receptors bind fibroblast growth factors, members of the largest family of growth factor ligands, comprising 22 members. So far, five distinct membrane FGFR have been identified in vertebrates and all of them belong to the tyrosine kinase superfamily (FGFR1 to FGFR4). - + @@ -4228,7 +4228,7 @@ This gene, a member of the histidine triad gene family, encodes a diadenosine 5',5'''-P1,P3-triphosphate hydrolase involved in purine metabolism. The gene encompasses the common fragile site FRA3B on chromosome 3, where carcinogen-induced damage can lead to translocations and aberrant transcripts of this gene. In fact, aberrant transcripts from this gene have been found in about half of all esophageal, stomach, and colon carcinomas. Alternatively spliced transcript variants have been found for this gene. - + @@ -4386,7 +4386,7 @@ This gene encodes one of the major intermediate filament proteins of mature astrocytes. It is used as a marker to distinguish astrocytes from other glial cells during development. Mutations in this gene cause Alexander disease, a rare disorder of astrocytes in the central nervous system. Alternative splicing results in multiple transcript variants encoding distinct isoforms. - + @@ -4415,7 +4415,7 @@ After removal of the precursor signal peptide, proinsulin is post-translationally cleaved into two chains (peptide A and peptide B) that are covalently linked via two disulfide bonds. Binding of this mature form of insulin to the insulin receptor (INSR) stimulates glucose uptake. A variety of mutant alleles with changes in the coding region have been identified. There is a read-through gene, INS-IGF2, which overlaps with this gene at the 5' region and with the IGF2 gene at the 3' region. - + @@ -4457,7 +4457,7 @@ After removal of the precursor signal peptide, the insulin receptor precursor is post-translationally cleaved into two chains (alpha and beta) that are covalently linked. Binding of insulin to the insulin receptor (INSR) stimulates glucose uptake. Two transcript variants encoding different isoforms have been found for this gene. - + @@ -4506,7 +4506,7 @@ This gene encodes a member of the type I (acidic) cytokeratin family, which belongs to the superfamily of intermediate filament (IF) proteins. Keratins are heteropolymeric structural proteins which form the intermediate filament. These filaments, along with actin microfilaments and microtubules, compose the cytoskeleton of epithelial cells. Mutations in this gene are associated with epidermolytic hyperkeratosis. This gene is located within a cluster of keratin family members on chromosome 17q21. - + @@ -4564,7 +4564,7 @@ The protein encoded by this gene is a member of the keratin gene family. The keratins are intermediate filament proteins responsible for the structural integrity of epithelial cells and are subdivided into cytokeratins and hair keratins. Most of the type I cytokeratins consist of acidic proteins which are arranged in pairs of heterotypic keratin chains. This type I cytokeratin is paired with keratin 4 and expressed in the suprabasal layers of non-cornified stratified epithelia. Mutations in this gene and keratin 4 have been associated with the autosomal dominant disorder White Sponge Nevus. The type I cytokeratins are clustered in a region of chromosome 17q21.2. Alternative splicing of this gene results in multiple transcript variants; however, not all variants have been described. - + @@ -4633,7 +4633,7 @@ This gene encodes a member of the keratin family, the most diverse group of intermediate filaments. This gene product, a type I keratin, is usually found as a heterotetramer with two keratin 5 molecules, a type II keratin. Together they form the cytoskeleton of epithelial cells. Mutations in the genes for these keratins are associated with epidermolysis bullosa simplex. At least one pseudogene has been identified at 17p12-p11. - + @@ -4704,7 +4704,7 @@ The protein encoded by this gene is a member of the keratin gene family. The keratins are intermediate filament proteins responsible for the structural integrity of epithelial cells and are subdivided into cytokeratins and hair keratins. Most of the type I cytokeratins consist of acidic proteins which are arranged in pairs of heterotypic keratin chains and are clustered in a region of chromosome 17q12-q21. This keratin has been coexpressed with keratin 14 in a number of epithelial tissues, including esophagus, tongue, and hair follicles. Mutations in this gene are associated with type 1 pachyonychia congenita, non-epidermolytic palmoplantar keratoderma and unilateral palmoplantar verrucous nevus. - + @@ -4883,7 +4883,7 @@ This gene encodes the type I intermediate filament chain keratin 17, expressed in nail bed, hair follicle, sebaceous glands, and other epidermal appendages. Mutations in this gene lead to Jackson-Lawler type pachyonychia congenita and steatocystoma multiplex. - + @@ -5077,7 +5077,7 @@ KRT18 encodes the type I intermediate filament chain keratin 18. Keratin 18, together with its filament partner keratin 8, are perhaps the most commonly found members of the intermediate filament gene family. They are expressed in single layer epithelial tissues of the body. Mutations in this gene have been linked to cryptogenic cirrhosis. Two transcript variants encoding the same protein have been found for this gene. - + @@ -5259,7 +5259,7 @@ The protein encoded by this gene is a member of the keratin family. The keratins are intermediate filament proteins responsible for the structural integrity of epithelial cells and are subdivided into cytokeratins and hair keratins. The type I cytokeratins consist of acidic proteins which are arranged in pairs of heterotypic keratin chains. Unlike its related family members, this smallest known acidic cytokeratin is not paired with a basic cytokeratin in epithelial cells. It is specifically expressed in the periderm, the transiently superficial layer that envelopes the developing epidermis. The type I cytokeratins are clustered in a region of chromosome 17q12-q21. - + @@ -5317,7 +5317,7 @@ The protein encoded by this gene is a member of the keratin gene family. The type II cytokeratins consist of basic or neutral proteins which are arranged in pairs of heterotypic keratin chains coexpressed during differentiation of simple and stratified epithelial tissues. This type II cytokeratin is specifically expressed in differentiated layers of the mucosal and esophageal epithelia with family member KRT13. Mutations in these genes have been associated with White Sponge Nevus, characterized by oral, esophageal, and anal leukoplakia. The type II cytokeratins are clustered in a region of chromosome 12q12-q13. - + @@ -5534,7 +5534,7 @@ The protein encoded by this gene is a member of the keratin gene family. The type II cytokeratins consist of basic or neutral proteins which are arranged in pairs of heterotypic keratin chains coexpressed during differentiation of simple and stratified epithelial tissues. This type II cytokeratin is specifically expressed in the simple epithelia lining the cavities of the internal organs and in the gland ducts and blood vessels. The genes encoding the type II cytokeratins are clustered in a region of chromosome 12q12-q13. Alternative splicing may result in several transcript variants; however, not all variants have been fully described. - + @@ -5744,7 +5744,7 @@ This gene is a member of the type II keratin family clustered on the long arm of chromosome 12. Type I and type II keratins heteropolymerize to form intermediate-sized filaments in the cytoplasm of epithelial cells. The product of this gene typically dimerizes with keratin 18 to form an intermediate filament in simple single-layered epithelial cells. This protein plays a role in maintaining cellular structural integrity and also functions in signal transduction and cellular differentiation. Mutations in this gene cause cryptogenic cirrhosis. - + @@ -5785,7 +5785,7 @@ The protein encoded by this gene is a member of the keratin gene family. The type II cytokeratins consist of basic or neutral proteins which are arranged in pairs of heterotypic keratin chains coexpressed during differentiation of simple and stratified epithelial tissues. As many as six of this type II cytokeratin (KRT6) have been identified; the multiplicity of the genes is attributed to successive gene duplication events. The genes are expressed with family members KRT16 and/or KRT17 in the filiform papillae of the tongue, the stratified epithelial lining of oral mucosa and esophagus, the outer root sheath of hair follicles, and the glandular epithelia. - + @@ -5916,7 +5916,7 @@ This gene is a member of the mucin family and encodes a membrane bound, glycosylated phosphoprotein. The protein is anchored to the apical surface of many epithelia by a transmembrane domain, with the degree of glycosylation varying with cell type. It also includes a 20 aa variable number tandem repeat (VNTR) domain, with the number of repeats varying from 20 to 120 in different individuals. The protein serves a protective function by binding to pathogens and also functions in a cell signaling capacity. Overexpression, aberrant intracellular localization, and changes in glycosylation of this protein have been associated with carcinomas. Multiple alternatively spliced transcript variants that encode different isoforms of this gene have been reported, but the full-length nature of only some has been determined. - + @@ -5957,7 +5957,7 @@ This gene encodes a member of the mucin protein family. Mucins are high molecular weight glycoproteins produced by many epithelial tissues. The protein encoded by this gene is secreted and forms an insoluble mucous barrier that protects the gut lumen. The protein polymerizes into a gel of which 80% is composed of oligosaccharide side chains by weight. The protein features a central domain containing tandem repeats rich in threonine and proline that varies between 50 and 115 copies in different individuals. Alternatively spliced transcript variants of this gene have been described, but their full-length nature is not known. - + @@ -6017,7 +6017,7 @@ The protein encoded by this gene is a multifunctional, nuclear phosphoprotein that plays a role in cell cycle progression, apoptosis and cellular transformation. It functions as a transcription factor that regulates transcription of specific target genes. Mutations, overexpression, rearrangement and translocation of this gene have been associated with a variety of hematopoietic tumors, leukemias and lymphomas, including Burkitt lymphoma. There is evidence to show that alternative translation initiations from an upstream, in-frame non-AUG (CUG) and a downstream AUG start site result in the production of two isoforms with distinct N-termini. The synthesis of non-AUG initiated protein is suppressed in Burkitt's lymphomas, suggesting its importance in the normal function of this gene. - + @@ -6053,7 +6053,7 @@ The mucin genes encode epithelial glycoproteins, some of which are secreted and some membrane bound. Each of the genes contains at least one large domain of tandemly repeated sequence that encodes the peptide sequence rich in serine and/or threonine residues, which carries most of the O-linked glycosylation. - + @@ -6102,7 +6102,7 @@ Receptor for glucocorticoids (GC). Has a dual mode of action: as a transcription factor that binds to glucocorticoid response elements (GRE) and as a modulator of other transcription factors. Affects inflammatory responses, cellular proliferation and differentiation in target tissues. Could act as a coactivator for STAT5-dependent transcription upon growth hormone (GH) stimulation and could reveal an essential role of hepatic GR in the control of body growth. Involved in chromatin remodeling. Plays a significant role in transactivation. Involved in nuclear translocation. - + @@ -6189,7 +6189,7 @@ The protein encoded by this gene was originally identified as a 44-kD glycoprotein that interacts with the NEU/ERBB2 receptor tyrosine kinase to increase its phosphorylation on tyrosine residues. This protein is a signaling protein that mediates cell-cell interactions and plays critical roles in the growth and development of multiple organ systems. It is known that an extraordinary variety of different isoforms are produced from this gene through alternative promoter usage and splicing. These isoforms are tissue-specifically expressed and differ significantly in their structure, and thereby these isoforms are classified into types I, II, III, IV, V and VI. The gene dysregulation has been linked to diseases such as cancer, schizophrenia and bipolar disorder (BPD). - + @@ -6621,7 +6621,7 @@ This gene encodes a member of the steroid receptor superfamily. The encoded protein mediates the physiological effects of progesterone, which plays a central role in reproductive events associated with the establishment and maintenance of pregnancy. This gene uses two distinct promotors and translation start sites in the first exon to produce two isoforms, A and B. The two isoforms are identical except for the additional 165 amino acids found in the N-terminus of isoform A only, and mediate their own response genes and physiologic effects with little overlap. The location of transcription initiation for isoform B has not been clearly determined. - + @@ -6687,7 +6687,7 @@ This gene was identified as a tumor suppressor that is mutated in a large number of cancers at high frequency. The protein encoded this gene is a phosphatidylinositol-3,4,5-trisphosphate 3-phosphatase. It contains a tensin like domain as well as a catalytic domain similar to that of the dual specificity protein tyrosine phosphatases. Unlike most of the protein tyrosine phosphatases, this protein preferentially dephosphorylates phosphoinositide substrates. It negatively regulates intracellular levels of phosphatidylinositol-3,4,5-trisphosphate in cells and functions as a tumor suppressor by negatively regulating AKT/PKB signaling pathway. - + @@ -6728,7 +6728,7 @@ P-glycoprotein is a well-characterized ABC-transporter of the MDR/TAP subfamily. The membrane-associated protein encoded by this gene is a member of the superfamily of ATP-binding cassette (ABC) transporters. ABC proteins transport various molecules across extra- and intra-cellular membranes. ABC genes are divided into seven distinct subfamilies (ABC1, MDR/TAP, MRP, ALD, OABP, GCN20, White). This protein is a member of the MDR/TAP subfamily. Members of the MDR/TAP subfamily are involved in multidrug resistance. - + @@ -6781,7 +6781,7 @@ This locus may represent a breast cancer candidate gene. It is located close to FGFR1 on a region of chromosome 8 that is amplified in some breast cancers. Three transcript variants encoding different isoforms have been found for this gene. - + @@ -6838,7 +6838,7 @@ This gene encodes a member of the transforming growth factor beta (TGFB) family of cytokines, which are multifunctional peptides that regulate proliferation, differentiation, adhesion, migration, and other functions in many cell types. Many cells have TGFB receptors, and the protein positively and negatively regulates many other growth factors. The secreted protein is cleaved into a latency-associated peptide (LAP) and a mature TGFB1 peptide, and is found in either a latent form composed of a TGFB1 homodimer, a LAP homodimer, and a latent TGFB1-binding protein, or in an active form composed of a TGFB1 homodimer. The mature peptide may also form heterodimers with other TGFB family members. This gene is frequently upregulated in tumor cells, and mutations in this gene result in Camurati-Engelmann disease. - + @@ -6939,7 +6939,7 @@ The protein encoded by this gene forms a heteromeric complex with type II TGF-beta receptors when bound to TGF-beta, transducing the TGF-beta signal from the cell surface to the cytoplasm. The encoded protein is a serine/threonine protein kinase. Mutations in this gene have been associated with Loeys-Dietz aortic aneurysm syndrome (LDAS). Multiple transcript variants encoding different isoforms have been found for this gene. - + @@ -7024,7 +7024,7 @@ This gene encodes a member of the Ser/Thr protein kinase family and the TGFB receptor subfamily. The encoded protein is a transmembrane protein that has a protein kinase domain, forms a heterodimeric complex with another receptor protein, and binds TGF-beta. This receptor/ligand complex phosphorylates proteins, which then enter the nucleus and regulate the transcription of a subset of genes related to cell proliferation. Mutations in this gene have been associated with Marfan Syndrome, Loeys-Deitz Aortic Aneurysm Syndrome, and the development of various types of tumors. Alternatively spliced transcript variants encoding different isoforms have been characterized. - + @@ -7108,7 +7108,7 @@ This gene encodes a multifunctional proinflammatory cytokine that belongs to the tumor necrosis factor (TNF) superfamily. This cytokine is mainly secreted by macrophages. It can bind to, and thus functions through its receptors TNFRSF1A/TNFR1 and TNFRSF1B/TNFBR. This cytokine is involved in the regulation of a wide spectrum of biological processes including cell proliferation, differentiation, apoptosis, lipid metabolism, and coagulation. This cytokine has been implicated in a variety of diseases, including autoimmune diseases, insulin resistance, and cancer. Knockout studies in mice also suggested the neuroprotective function of this cytokine. - + @@ -7422,7 +7422,7 @@ This gene encodes tumor protein p53, which responds to diverse cellular stresses to regulate target genes that induce cell cycle arrest, apoptosis, senescence, DNA repair, or changes in metabolism. p53 protein is expressed at low level in normal cells and at a high level in a variety of transformed cell lines, where it's believed to contribute to transformation and malignancy. p53 is a DNA-binding protein containing transcription activation, DNA-binding, and oligomerization domains. It is postulated to bind to a p53-binding site and activate expression of downstream genes that inhibit growth and/or invasion, and thus function as a tumor suppressor. Mutants of p53 that frequently occur in a number of different human cancers fail to bind the consensus DNA binding site, and hence cause the loss of tumor suppressor activity. Alterations of this gene occur not only as somatic mutations in human malignancies, but also as germline mutations in some cancer-prone families with Li-Fraumeni syndrome. Multiple p53 variants due to alternative promoters and multiple alternative splicing have been found. These variants encode distinct isoforms, which can regulate p53 transcriptional activity. - + @@ -7579,7 +7579,7 @@ This gene encodes a member of the intermediate filament family. Intermediate filamentents, along with microtubules and actin microfilaments, make up the cytoskeleton. The protein encoded by this gene is responsible for maintaining cell shape, integrity of the cytoplasm, and stabilizing cytoskeletal interactions. It is also involved in the immune response, and controls the transport of low-density lipoprotein (LDL)-derived cholesterol from a lysosome to the site of esterification. It functions as an organizer of a number of critical proteins involved in attachment, migration, and cell signaling. Mutations in this gene causes a dominant, pulverulent cataract. - + @@ -7628,7 +7628,7 @@ The WNT gene family consists of structurally related genes which encode secreted signaling proteins. These proteins have been implicated in oncogenesis and in several developmental processes, including regulation of cell fate and patterning during embryogenesis. This gene is a member of the WNT gene family. It encodes a protein which shows 98% amino acid identity to mouse Wnt3 protein, and 84% to human WNT3A protein, another WNT gene product. The mouse studies show the requirement of Wnt3 in primary axis formation in the mouse. Studies of the gene expression suggest that this gene may play a key role in some cases of human breast, rectal, lung, and gastric cancer through activation of the WNT-beta-catenin-TCF signaling pathway. This gene is clustered with WNT15, another family member, in the chromosome 17q21 region. - + @@ -7682,7 +7682,7 @@ The WNT gene family consists of structurally related genes which encode secreted signaling proteins. These proteins have been implicated in oncogenesis and in several developmental processes, including regulation of cell fate and patterning during embryogenesis. This gene is a member of the WNT gene family. It encodes a protein which shows 98%, 98% and 87% amino acid identity to the mouse, rat and the xenopus Wnt5A protein, respectively. The experiments performed in Xenopus laevis embryos identified that human frizzled-5 (hFz5) is the receptor for the Wnt5A ligand and the Wnt5A/hFz5 signaling mediates axis induction. - + @@ -7706,7 +7706,7 @@ This gene is a member of the WNT gene family, which consists of structurally related genes that encode secreted signaling proteins. These proteins have been implicated in oncogenesis and in several developmental processes, including regulation of cell fate and patterning during embryogenesis. Among members of the human WNT family, this gene product is most similar to WNT7A protein. - + @@ -7714,7 +7714,7 @@ cell line - + @@ -7731,7 +7731,7 @@ - + @@ -7741,7 +7741,7 @@ >normal human cell line - + @@ -7756,7 +7756,7 @@ - + @@ -7797,7 +7797,7 @@ - + @@ -7830,7 +7830,7 @@ - + @@ -7865,7 +7865,7 @@ - + @@ -7886,7 +7886,7 @@ - + @@ -7933,7 +7933,7 @@ - + @@ -7948,7 +7948,7 @@ - + @@ -7975,7 +7975,7 @@ - + @@ -8002,7 +8002,7 @@ - + @@ -8029,7 +8029,7 @@ - + @@ -8056,7 +8056,7 @@ - + @@ -8083,7 +8083,7 @@ - + @@ -8122,7 +8122,7 @@ - + @@ -8149,7 +8149,7 @@ - + @@ -8176,7 +8176,7 @@ - + @@ -8203,7 +8203,7 @@ - + @@ -8230,7 +8230,7 @@ - + @@ -8257,7 +8257,7 @@ - + @@ -8284,7 +8284,7 @@ - + @@ -8299,7 +8299,7 @@ - + @@ -8330,7 +8330,7 @@ MCF10A cells (human mammary epithelial cells) stably expressing c-Myc. - + @@ -8405,7 +8405,7 @@ - + @@ -8450,7 +8450,7 @@ - + @@ -8543,7 +8543,7 @@ - + @@ -8636,7 +8636,7 @@ - + @@ -8679,7 +8679,7 @@ Human non cancer breast epithelial cells immortalized by infection with the retrovirus pBabepuro+hTERT vectorline - + @@ -8695,7 +8695,7 @@ - + @@ -8705,7 +8705,7 @@ >pathological human cell line - + @@ -8738,7 +8738,7 @@ - + @@ -8771,7 +8771,7 @@ - + @@ -8840,7 +8840,7 @@ - + @@ -8947,7 +8947,7 @@ - + @@ -8974,7 +8974,7 @@ - + @@ -9063,7 +9063,7 @@ - + @@ -9170,7 +9170,7 @@ - + @@ -9301,7 +9301,7 @@ - + @@ -9354,7 +9354,7 @@ - + @@ -9425,7 +9425,7 @@ - + @@ -9506,7 +9506,7 @@ - + @@ -9593,7 +9593,7 @@ - + @@ -9674,7 +9674,7 @@ - + @@ -9743,7 +9743,7 @@ - + @@ -9814,7 +9814,7 @@ - + @@ -9895,7 +9895,7 @@ - + @@ -9978,7 +9978,7 @@ - + @@ -10059,7 +10059,7 @@ - + @@ -10164,7 +10164,7 @@ - + @@ -10269,7 +10269,7 @@ - + @@ -10374,7 +10374,7 @@ - + @@ -10443,7 +10443,7 @@ - + @@ -10482,7 +10482,7 @@ - + @@ -10503,7 +10503,7 @@ - + @@ -10548,7 +10548,7 @@ - + @@ -10631,7 +10631,7 @@ - + @@ -10750,7 +10750,7 @@ - + @@ -10827,7 +10827,7 @@ - + @@ -10904,7 +10904,7 @@ - + @@ -10981,7 +10981,7 @@ - + @@ -11076,7 +11076,7 @@ - + @@ -11171,7 +11171,7 @@ - + @@ -11284,7 +11284,7 @@ - + @@ -11379,7 +11379,7 @@ - + @@ -11414,7 +11414,7 @@ - + @@ -11509,7 +11509,7 @@ - + @@ -11658,7 +11658,7 @@ - + @@ -11729,7 +11729,7 @@ - + @@ -11806,7 +11806,7 @@ - + @@ -11877,7 +11877,7 @@ - + @@ -11930,7 +11930,7 @@ - + @@ -12019,7 +12019,7 @@ - + @@ -12070,7 +12070,7 @@ - + @@ -12157,7 +12157,7 @@ - + @@ -12238,7 +12238,7 @@ - + @@ -12265,7 +12265,7 @@ - + @@ -12388,7 +12388,7 @@ - + @@ -12441,7 +12441,7 @@ - + @@ -12482,7 +12482,7 @@ - + @@ -12523,7 +12523,7 @@ - + @@ -12564,7 +12564,7 @@ - + @@ -12605,7 +12605,7 @@ - + @@ -12646,7 +12646,7 @@ - + @@ -12687,7 +12687,7 @@ - + @@ -12756,7 +12756,7 @@ - + @@ -12797,7 +12797,7 @@ - + @@ -12838,7 +12838,7 @@ - + @@ -12879,7 +12879,7 @@ - + @@ -12920,7 +12920,7 @@ - + @@ -12961,7 +12961,7 @@ - + @@ -13002,7 +13002,7 @@ - + @@ -13043,7 +13043,7 @@ - + @@ -13076,7 +13076,7 @@ - + @@ -13103,7 +13103,7 @@ - + @@ -13130,7 +13130,7 @@ - + @@ -13243,7 +13243,7 @@ - + @@ -13324,7 +13324,7 @@ - + @@ -13369,7 +13369,7 @@ - + @@ -13408,7 +13408,7 @@ - + @@ -13435,7 +13435,7 @@ - + @@ -13462,7 +13462,7 @@ - + @@ -13490,7 +13490,7 @@ - + @@ -13511,7 +13511,7 @@ - + @@ -13558,7 +13558,7 @@ - + @@ -13609,7 +13609,7 @@ - + @@ -13678,7 +13678,7 @@ - + @@ -13735,7 +13735,7 @@ - + @@ -13804,7 +13804,7 @@ - + @@ -13825,7 +13825,7 @@ - + @@ -13846,7 +13846,7 @@ - + @@ -13873,7 +13873,7 @@ - + @@ -13894,7 +13894,7 @@ - + @@ -14023,7 +14023,7 @@ - + @@ -14062,7 +14062,7 @@ - + @@ -14101,7 +14101,7 @@ - + @@ -14140,7 +14140,7 @@ - + @@ -14185,7 +14185,7 @@ - + @@ -14230,7 +14230,7 @@ - + @@ -14275,7 +14275,7 @@ - + @@ -14314,7 +14314,7 @@ - + @@ -14341,7 +14341,7 @@ - + @@ -14362,7 +14362,7 @@ - + @@ -14401,7 +14401,7 @@ - + @@ -14422,7 +14422,7 @@ - + @@ -14491,7 +14491,7 @@ - + @@ -14524,7 +14524,7 @@ - + @@ -14563,7 +14563,7 @@ - + @@ -14617,7 +14617,7 @@ - + @@ -14638,7 +14638,7 @@ - + @@ -14692,7 +14692,7 @@ - + @@ -14725,7 +14725,7 @@ - + @@ -14782,7 +14782,7 @@ - + @@ -14835,7 +14835,7 @@ - + @@ -14912,7 +14912,7 @@ - + @@ -14971,7 +14971,7 @@ - + @@ -15030,7 +15030,7 @@ - + @@ -15119,7 +15119,7 @@ - + @@ -15152,7 +15152,7 @@ - + @@ -15185,7 +15185,7 @@ - + @@ -15232,7 +15232,7 @@ - + @@ -15303,7 +15303,7 @@ - + @@ -15362,7 +15362,7 @@ - + @@ -15421,7 +15421,7 @@ - + @@ -15534,7 +15534,7 @@ - + @@ -15629,7 +15629,7 @@ - + @@ -15675,7 +15675,7 @@ - + @@ -15780,7 +15780,7 @@ - + @@ -15861,7 +15861,7 @@ - + @@ -15882,7 +15882,7 @@ - + @@ -15927,7 +15927,7 @@ - + @@ -15966,7 +15966,7 @@ - + @@ -16005,7 +16005,7 @@ - + @@ -16038,7 +16038,7 @@ - + @@ -16133,7 +16133,7 @@ - + @@ -16168,7 +16168,7 @@ - + @@ -16203,7 +16203,7 @@ - + @@ -16272,7 +16272,7 @@ - + @@ -16311,7 +16311,7 @@ - + @@ -16376,7 +16376,7 @@ - + @@ -16415,7 +16415,7 @@ - + @@ -16460,7 +16460,7 @@ - + @@ -16505,7 +16505,7 @@ - + @@ -16556,7 +16556,7 @@ - + @@ -16589,7 +16589,7 @@ - + @@ -16700,7 +16700,7 @@ - + @@ -16807,7 +16807,7 @@ - + @@ -16848,7 +16848,7 @@ - + @@ -16959,7 +16959,7 @@ - + @@ -16992,7 +16992,7 @@ - + @@ -17033,7 +17033,7 @@ - + @@ -17054,7 +17054,7 @@ - + @@ -17135,7 +17135,7 @@ - + @@ -17216,7 +17216,7 @@ - + @@ -17237,7 +17237,7 @@ - + @@ -17258,7 +17258,7 @@ - + @@ -17279,7 +17279,7 @@ - + @@ -17360,7 +17360,7 @@ - + @@ -17381,7 +17381,7 @@ - + @@ -17408,7 +17408,7 @@ - + @@ -17471,7 +17471,7 @@ - + @@ -17492,7 +17492,7 @@ - + @@ -17513,7 +17513,7 @@ - + @@ -17552,7 +17552,7 @@ - + @@ -17562,7 +17562,7 @@ >pathological mouse cell line - + @@ -17603,7 +17603,7 @@ The 4T1 cell line was derived from a spontaneously arising BALB/c mammary tumor - + @@ -17612,7 +17612,7 @@ chemicals and drugs - + @@ -17624,7 +17624,7 @@ Inhibitors of hormonal activity - + @@ -17635,7 +17635,7 @@ Inhibitors of estrogen hormone activity - + @@ -17670,7 +17670,7 @@ - + @@ -17728,7 +17728,7 @@ - + @@ -17739,7 +17739,7 @@ A generic term for fats and lipoids, the alcohol-ether-soluble constituents of protoplasm, which are insoluble in water. They comprise the fats, fatty oils, essential oils, waxes, phospholipids, glycolipids, sulfolipids, aminolipids, chromolipids (lipochromes), and fatty acids. - + @@ -17799,7 +17799,7 @@ Organic, monobasic acids derived from hydrocarbons by the equivalent of oxidation of a methyl group to an alcohol, aldehyde, and then acid. Fatty acids are saturated and unsaturated. - + @@ -17830,7 +17830,7 @@ - + @@ -17842,7 +17842,7 @@ A broad class of substances containing carbon and its derivatives. Many of these chemicals will frequently contain hydrogen with or without oxygen, nitrogen, sulfur, phosphorus, and other elements. They exist in either carbon chain or carbon ring form. - + @@ -17851,7 +17851,7 @@ hydrocarbons - + @@ -17876,7 +17876,7 @@ A class of compounds composed of repeating 5-carbon units of hemiterpenes - + @@ -17901,7 +17901,7 @@ The general name for a group of fat-soluble pigments found in green, yellow, and leafy vegetables, and yellow fruits. They are aliphatic hydrocarbons consisting of a polyisoprene backbone. - + @@ -17912,7 +17912,7 @@ A group of tetraterpenes, with four terpene units joined head-to-tail. Biologically active members of this class are used clinically in the treatment of severe cystic acne; psoriasis; and other disorders of keratinization. - + @@ -17960,7 +17960,7 @@ Retinol and derivatives of retinol that play an essential role in metabolic functioning of the retina, the growth of and differentiation of epithelial tissue, the growth of bone, reproduction, and the immune response. Dietary vitamin A is derived from a variety of carotenoids found in plants. It is enriched in the liver, egg yolks, and the fat component of dairy products. - + @@ -18101,7 +18101,7 @@ An important regulator of gene expression during growth and development, and in neoplasms. Tretinoin, also known as retinoic acid and derived from maternal vitamin A, is essential for normal growth; and embryonic development. An excess of tretinoin can be teratogenic. It is used in the treatment of psoriasis; acne vulgaris; and several other skin diseases. It has also been approved for use in promyelocytic leukemia (leukemia, promyelocytic, acute). - + @@ -18158,7 +18158,7 @@ Twenty-carbon compounds derived from mavalonic acid or deoxyxylulose phosphate. - + @@ -18169,7 +18169,7 @@ The parent alcohol of the tumor promoting compounds from croton oil (Croton tiglium). - + @@ -18200,7 +18200,7 @@ Tumor-promoting compounds obtained from croton oil (Croton tiglium). Some of these are used in cell biological experiments as activators of protein kinase C. - + @@ -18284,7 +18284,7 @@ A phorbol ester found in croton oil with very effective tumor promoting activity. It stimulates the synthesis of both DNA and RNA. - + @@ -18296,7 +18296,7 @@ Compounds inhibiting receptor activity - + @@ -18308,7 +18308,7 @@ Compounds inhibitng ERBB2 receptor activity. - + @@ -18320,7 +18320,7 @@ Compounds used in treatment of various pathological conditions. - + @@ -18401,7 +18401,7 @@ Substances that reduce the growth or reproduction of bacteria. - + @@ -18428,7 +18428,7 @@ - + @@ -18464,7 +18464,7 @@ Zeocin is a member of the bleomycin/phleomycin family of antibiotics, known to bind and cleave DNA. - + @@ -18474,7 +18474,7 @@ >antineoplastic agent - + @@ -18730,7 +18730,7 @@ Antineoplastic antibiotic obtained from Streptomyces peucetius. It is a hydroxy derivative of daunorubicin. - + @@ -18877,7 +18877,7 @@ An anthracycline which is the 4'-epi-isomer of doxorubicin. The compound exerts its antitumor effects by interference with the synthesis and function of DNA. - + @@ -19143,7 +19143,7 @@ A semisynthetic derivative of podophyllotoxin that exhibits antitumor activity. Etoposide inhibits DNA synthesis by forming a complex with topoisomerase II and DNA. This complex induces breaks in double stranded DNA and prevents repair by topoisomerase II binding. Accumulated breaks in DNA prevent entry into the mitotic phase of cell division, and lead to cell death. Etoposide acts primarily in the G2 and S phases of the cell cycle. - + @@ -19173,7 +19173,7 @@ - + @@ -19354,7 +19354,7 @@ An anthracenedione-derived antineoplastic agent. - + @@ -19363,7 +19363,7 @@ genetic variation - + @@ -19373,7 +19373,7 @@ >chromosomal mutation - + @@ -19383,7 +19383,7 @@ >chromosomal deletion - + @@ -19394,7 +19394,7 @@ - + @@ -19404,7 +19404,7 @@ >deletion in short arm - + @@ -19426,7 +19426,7 @@ - + @@ -19448,7 +19448,7 @@ - + @@ -19470,7 +19470,7 @@ - + @@ -19479,7 +19479,7 @@ gene mutation - + @@ -19488,7 +19488,7 @@ deletion - + @@ -19497,7 +19497,7 @@ exon deletion - + @@ -19525,7 +19525,7 @@ - + @@ -19553,7 +19553,7 @@ - + @@ -19581,7 +19581,7 @@ - + @@ -19621,7 +19621,7 @@ - + @@ -19649,7 +19649,7 @@ - + @@ -19658,7 +19658,7 @@ duplication - + @@ -19668,7 +19668,7 @@ >exon duplication - + @@ -19697,7 +19697,7 @@ - + @@ -19725,7 +19725,7 @@ - + @@ -19735,7 +19735,7 @@ >gene duplication - + @@ -19763,7 +19763,7 @@ - + @@ -19827,7 +19827,7 @@ - + @@ -19873,7 +19873,7 @@ - + @@ -19901,7 +19901,7 @@ - + @@ -19929,7 +19929,7 @@ - + @@ -19957,7 +19957,7 @@ - + @@ -19966,7 +19966,7 @@ insertion - + @@ -19994,7 +19994,7 @@ - + @@ -20022,7 +20022,7 @@ - + @@ -20031,7 +20031,7 @@ point mutation - + @@ -20041,7 +20041,7 @@ >nonsense mutation - + @@ -20067,7 +20067,7 @@ - + @@ -20093,7 +20093,7 @@ - + @@ -20119,7 +20119,7 @@ - + @@ -20145,7 +20145,7 @@ - + @@ -20171,7 +20171,7 @@ - + @@ -20197,7 +20197,7 @@ - + @@ -20206,7 +20206,7 @@ transition - + @@ -20234,7 +20234,7 @@ - + @@ -20262,7 +20262,7 @@ - + @@ -20290,7 +20290,7 @@ - + @@ -20318,7 +20318,7 @@ - + @@ -20358,7 +20358,7 @@ - + @@ -20386,7 +20386,7 @@ - + @@ -20414,7 +20414,7 @@ - + @@ -20442,7 +20442,7 @@ - + @@ -20451,7 +20451,7 @@ transversion - + @@ -20479,7 +20479,7 @@ - + @@ -20507,7 +20507,7 @@ - + @@ -20535,7 +20535,7 @@ - + @@ -20563,7 +20563,7 @@ - + @@ -20591,7 +20591,7 @@ - + @@ -20619,7 +20619,7 @@ - + @@ -20647,7 +20647,7 @@ - + @@ -20656,7 +20656,7 @@ pathological condition - + @@ -20667,7 +20667,7 @@ New abnormal growth of tissue. Malignant neoplasms show a greater degree of anaplasia and have the properties of invasion and metastasis, compared to benign neoplasms. - + @@ -20697,7 +20697,7 @@ Invasive form of papillary ductal cercinoma of the breast. - + @@ -20709,7 +20709,7 @@ Benign tumors of the breast. - + @@ -20798,7 +20798,7 @@ A noninvasive (noninfiltrating) carcinoma of the breast characterized by a proliferation of malignant epithelial cells confined to the mammary ducts or lobules, without light-microscopy evidence of invasion through the basement membrane into the surrounding stroma. - + @@ -20810,7 +20810,7 @@ Although the name includes the term carcinoma, lobular carcinoma in situ (LCIS) is not really cancer, but rather a noninvasive condition that increases the risk of developing cancer in the future. LCIS, also known as lobular neoplasia or stage 0 breast cancer, occurs when abnormal cells accumulate in the breast lobules. Each breast has hundreds of milk producing lobules, which are connected to the milk ducts. In LCIS, the abnormal cells are often found throughout the breast lobules and both breasts are affected about 30 percent of the time. - + @@ -20828,7 +20828,7 @@ Primary acantholytic squamous cell carcinoma (ASCC) of the breast is a rare and aggressive variant of invasive breast cancer. - + @@ -20978,7 +20978,7 @@ Adenocarcinoma of the breast. - + @@ -21038,7 +21038,7 @@ Pathological processes of the breast. - + @@ -21214,7 +21214,7 @@ A common and benign breast disease characterized by varying degree of fibrocystic changes in the breast tissue. There are three major patterns of morphological changes, including fibrosis, formation of cysts, and proliferation of glandular tissue (adenosis). The fibrocystic breast has a dense irregular, lumpy, bumpy consistency. - + @@ -21433,7 +21433,7 @@ Neoplasm of the breast. - + @@ -22030,7 +22030,7 @@ An invasive (infiltrating) carcinoma of the mammary ductal system (mammary glands) in the human breast. - + @@ -22072,7 +22072,7 @@ Inflammatory Breast Cancer (IBC) is a very aggressive type of breast cancer in which the cancer cells block the lymph vessels in the skin of the breast. This type of breast cancer is called “inflammatory” because the breast often looks swollen and red, or “inflamed”, sometimes overnight and can be misdiagnosed as mastitis. Invasion of the local lymphatic ducts impairs drainage and causes edematous swelling of the breast. - + @@ -22306,7 +22306,7 @@ Metastatic carcinoma of the breast. - + @@ -22324,7 +22324,7 @@ Medullary carcinoma of the breast is a variant of breast cancer. These tumors have a similar presentation to other breast cancers but are distinguished by a characteristic histologic appearance. In addition, pure medullary carcinomas have a better prognosis than usual cases of infiltrating ductal carcinoma. - + @@ -22336,7 +22336,7 @@ Mucinous (colloid) carcinoma is a rare type of invasive breast cancer that is formed when cancer cells within your breast produce mucous. This mucous contains breast cancer cells that are easily distinguished from normal cells under a microscope. Together, the mucous and cancer cells form a jelly-like tumor. Most mucinous carcinomas of the breast are estrogen-receptor positive and HER2/neu negative. This type of breast cancer rarely spreads to your lymph nodes. - + @@ -22348,7 +22348,7 @@ Papillary carcinoma is a type of ductal carcinoma in situ (DCIS). This type of breast cancer is rarely invasive, and usually stays within the milk ducts of your breast. Papilla (a projection) refers to the microscopic shape of the cancer cells, which resemble fingers, or threads. - + @@ -22366,7 +22366,7 @@ An infiltrating ductal breast carcinoma associated with stromal fibrosis. - + @@ -22378,7 +22378,7 @@ SCC of the breast was first reported in 1908 by Troell. It is thought to arise directly from the epithelium of the mammary ducts, although an alternate theory is that the tumor arises from foci of squamous metaplasia within a preexisting adenocarcinoma of the breast. Squamous cell carcinoma (SCC) of the breast is rare and generally aggressive. - + @@ -22390,7 +22390,7 @@ Tubular carcinoma is a rare type of invasive ductal carcinoma of the breast. It takes its name from its microscopic appearance, in which the cancer cells resemble small tubes. Tubular carcinomas tend to be small, estrogen-receptor positive, HER2/neu negative. In some cases, tubular cancer cells are mixed with ductal or lobular cancer cells, giving a mixed-tumor diagnosis. - + @@ -22408,7 +22408,7 @@ Invasive Lobular Carcinoma (ILC) is a type of breast cancer that starts in the lobules of your breast, where milk is produced. At first, the cancer cells are at work in the lining of the milk lobes, but later these cells invade, or infiltrate, the nearby tissue outside of the lobes. As with invasive ductal carcinoma (IDC), ILC has the potential to spread, or metastasize, to other parts of your body. - + @@ -22420,7 +22420,7 @@ Within the abdominal cavity, nodes occur in chains along the main branches of the arteries of the intestine and the abdominal aorta. - + @@ -22431,7 +22431,7 @@ Biological entity, which constitutes the structural organization of a biological organism, or is an attribute of that organization. - + @@ -22449,7 +22449,7 @@ These nodes are in the underarm region and receive lymph from vessels that drain the arm, the walls of the thorax, the breast, and the upper walls of the abdomen. - + @@ -22461,7 +22461,7 @@ Anatomical areas of the body. - + @@ -22540,7 +22540,7 @@ The part of Central Nervous System that is contained within the skull (cranium). Arising from the neural tube, the embryonic brain is comprised of three major parts including prosencephalon (the forebrain); mesencephalon (the midbrain); and rhombencephalon (the hindbrain). The developed brain consists of cerebrum; cerebellum; and other structures in the brain stem. - + @@ -22569,7 +22569,7 @@ The main information-processing organs of the nervous system, consisting of the brain, spinal cord, and meninges. - + @@ -22587,7 +22587,7 @@ Nodules in chest wall - + @@ -22598,7 +22598,7 @@ Exocrine glands are glands that secrete their products (hormones) into ducts (duct glands) - + @@ -22609,7 +22609,7 @@ The body's defense mechanism against foreign organisms or substances and deviant native cells. It includes the humoral immune response and the cell-mediated response and consists of a complex of interrelated cellular, molecular, and genetic components. - + @@ -22621,7 +22621,7 @@ These nodes receive lymph from the legs, the outer portion of the genitalia and the lower abdominal wall. - + @@ -22680,7 +22680,7 @@ Either of the pair of organs occupying the cavity of the thorax that effect the aeration of the blood. - + @@ -22691,7 +22691,7 @@ They are oval or bean shaped bodies (1 - 30 mm in diameter) located along the lymphatic system. - + @@ -22703,7 +22703,7 @@ These nodes are grouped along the lower border of the jaw, in front of and behind the ears, and deep in the neck along the larger blood vessels. They drain the skin of the scalp, face, tissues of the nasal cavity, and the pharynx. - + @@ -22715,7 +22715,7 @@ A system of organs and tissues that process and transport immune cells and lymph. - + @@ -22797,7 +22797,7 @@ Specialized tissues that are components of the lymphatic system. They provide fixed locations within the body where a variety of lymphocytes can form, mature and multiply. The lymphoid tissues are connected by a network of lymphatic vessels. - + @@ -23980,7 +23980,7 @@ Glandular tissue in the breast that is under the influence of hormones such as estrogens; progestins; and prolactin. After parturition, the mammary glands secrete milk for the nourishment of the young. - + @@ -23991,7 +23991,7 @@ The entire nerve apparatus, composed of a central part, the brain and spinal cord, and a peripheral part, the cranial and spinal nerves, autonomic ganglia, and plexuses. - + @@ -24003,7 +24003,7 @@ The nodes here appear mostly along the paths of the blood vessels within the pelvic cavity and receive lymph from the lymphatic vessels in the area. - + @@ -24037,7 +24037,7 @@ The tubular and cavernous organs and structures, by means of which pulmonary ventilation and gas exchange between ambient air and the blood are brought about. - + @@ -24049,7 +24049,7 @@ These nodes occur between the lungs and along the windpipe and bronchi, and receive lymph from this area and from the internal wall of the thorax. - + @@ -24060,7 +24060,7 @@ The outer margins of the thorax containing skin, deep fascia; thorasic vertebrae; ribs; sternum; and muscles. - + @@ -24077,7 +24077,7 @@ The upper part of the trunk between the neck and the abdomen. It contains the chief organs of the circulatory and respiratory systems. - + @@ -24089,7 +24089,7 @@ Collections of differentiated cells, such as epithelium; connective tissue; muscles; and nerve tissue. Tissues are cooperatively arranged to form organs with specialized functions such as respiration; digestion; reproduction; movement; and others. - + @@ -24099,7 +24099,7 @@ Mouse embryo fibroblasts - + @@ -24119,7 +24119,7 @@ - + @@ -24139,7 +24139,7 @@ - + @@ -24153,7 +24153,7 @@ - + @@ -24173,7 +24173,7 @@ - + @@ -24187,7 +24187,7 @@ - + @@ -24201,7 +24201,7 @@ - + @@ -24223,7 +24223,7 @@ The 308 cell line is a papilloma-derived keratinocyte cell line from 7,12-dimethylbenz[a]anthracene-treated adult BALB/c mouse skin - + @@ -24233,7 +24233,7 @@ Mouse 30A5 preadipocytes is a cell line derived from 10Tl 2 fibroblasts - + @@ -24267,7 +24267,7 @@ An immortalized myeloblast-like cell line originally derived from long-term cultures of murine bone marrow. The most frequently employed subline is 32D clone 3 (32D cl3). - + @@ -24277,7 +24277,7 @@ Hematopoietic, immature myeloid, nontumorigenic, diploid cell line that is strictly dependent on exogenously supplied interleukin-3 (IL-3) for maintenance of its growth in culture. - + @@ -24287,7 +24287,7 @@ 3T3-C2 fibroblastic cells, a nondifferentiated subline of 3T3-L1, follow adipogenic process till mitotic clonal expansion stage (2 days after hormonal induction), but do not proceed to terminal differentitation. - + @@ -24297,7 +24297,7 @@ These cells (often just referred to as F442A cells) are one of several cloned cell lines established from disaggregated Swiss mouse embryos that are capable of differentiating into cells resembling adipocytes. The cells have the morphology of fibroblasts. When the cells reach confluence they spontaneously arrest growth and can be induced to differentiate into white adipocytes in vitro. They also yield a fully differentiated fat pad after subcutaneous injection into nude mice. These cells are used widely as a model system for pre-adypocytes to study the differentiation of adipocytes. - + @@ -24325,7 +24325,7 @@ L1 is a continuous substrain of 3T3 (Swiss albino) developed through clonal isolation. The cells undergo a pre-adipose to adipose like conversion as they progress from a rapidly dividing to a confluent and contact inhibited state. A high serum content in the medium enhances fat accumulation. - + @@ -24339,7 +24339,7 @@ - + @@ -24359,7 +24359,7 @@ - + @@ -24379,7 +24379,7 @@ - + @@ -24399,7 +24399,7 @@ - + @@ -24419,7 +24419,7 @@ - + @@ -24429,7 +24429,7 @@ Derived following HIV infection of A3.01. Contains a single integrated copy of defective HIV provirus - + @@ -24439,7 +24439,7 @@ Derivative of 8E5; retains HIV provirus but does not express HIV proteins. - + @@ -24453,7 +24453,7 @@ - + @@ -24473,7 +24473,7 @@ - + @@ -24493,7 +24493,7 @@ - + @@ -24515,7 +24515,7 @@ The A-431 cell line was derived from an epidermoid carcinoma excised from the skin tissue of an 85-year-old female. - + @@ -24531,7 +24531,7 @@ The A10 cell line was derived from the thoracic aorta of embryonic rat and is a commonly used model of vascular smooth muscle cells (VSMC). - + @@ -24545,7 +24545,7 @@ - + @@ -24555,7 +24555,7 @@ HAT-sensitive derivative of CEM obtained by treatment with 8-azaguanine. A3.01 is a hypoxanthine/aminopterin/thymidine-sensitive, human immunodeficiency virus-susceptible, human T cell line. - + @@ -24577,7 +24577,7 @@ This line was cloned by limiting dilution from the A375 melanoma cell line - + @@ -24597,7 +24597,7 @@ - + @@ -24607,7 +24607,7 @@ The ACH2 cell line is a clonal cell line derived following infection of A3.01 T cells with HIV-1. - + @@ -24627,7 +24627,7 @@ - + @@ -24641,7 +24641,7 @@ - + @@ -24693,7 +24693,7 @@ The AML12 (alpha mouse liver 12) cell line was established from hepatocytes from a mouse (CD1 strain, line MT42) transgenic for human TGF alpha. By electron microscopy, these cells exhibit typical hepatocyte features such as peroxisomes and bile canalicular like structure. AML12 cells retain the capacity to express high levels of mRNA for serum (albumin, alpha 1 antitrypsin and transferrin) and gap junction (connexins 26 and 32) proteins, and contain solely isoenzyme 5 of lactate dehydrogenase. - + @@ -24709,7 +24709,7 @@ Macrophage cell line derived from the bone marrow of C57BL/6 mice - + @@ -24731,7 +24731,7 @@ AR42J cells derive from azaserine-induced malignant nodules from the rat pancreas. AR42J cells represent the first amphicrine pancreatic cell line with the combined expression of exocrine and neuroendocrine secretory organelles, both of which follow a regulated secretory pathway in response to various secretory stimuli. - + @@ -24753,7 +24753,7 @@ Human anaplastic thyroid cancer cell line - + @@ -24769,7 +24769,7 @@ ARPE-19 is a human diploid retinal pigment epithelium (RPE) cell line, which is in many ways similar to RPE in vivo. - + @@ -24789,7 +24789,7 @@ - + @@ -24809,7 +24809,7 @@ - + @@ -24829,7 +24829,7 @@ - + @@ -24837,7 +24837,7 @@ - + @@ -24851,7 +24851,7 @@ - + @@ -24859,7 +24859,7 @@ - + @@ -24873,7 +24873,7 @@ - + @@ -24895,7 +24895,7 @@ An Epstein-Barr virus (EBV)-producer line, designated Akata, was established from a Japanese patient with Burkitt's lymphoma. The Akata line possessed the Burkitt's-type chromosome translocation, t(8q- ; 14q+), and was derived from the tumor cell. Akata cells produced a large quantity of transforming virus upon treatment of cells with anti-immunoglobulin antibodies. Southern blot analysis of viral DNA indicated that the Akata EBV is nondefective and more representative of wild-type viruses. Akata cells should be useful as a source of EBV. - + @@ -24909,7 +24909,7 @@ - + @@ -24917,7 +24917,7 @@ - + @@ -24931,7 +24931,7 @@ - + @@ -24939,7 +24939,7 @@ - + @@ -24947,7 +24947,7 @@ - + @@ -24955,7 +24955,7 @@ - + @@ -24977,7 +24977,7 @@ The line was derived from nude mouse xenografts initiated with cells from the ascites of a patient with cancer of the pancreas. - + @@ -24991,7 +24991,7 @@ - + @@ -24999,7 +24999,7 @@ - + @@ -25013,7 +25013,7 @@ - + @@ -25033,7 +25033,7 @@ - + @@ -25053,7 +25053,7 @@ - + @@ -25073,7 +25073,7 @@ - + @@ -25093,7 +25093,7 @@ - + @@ -25113,7 +25113,7 @@ - + @@ -25133,7 +25133,7 @@ - + @@ -25161,7 +25161,7 @@ TNF-alpha gene-transduced B78 melanoma cells - + @@ -25175,7 +25175,7 @@ - + @@ -25195,7 +25195,7 @@ - + @@ -25215,7 +25215,7 @@ - + @@ -25237,7 +25237,7 @@ A cell line established from a spontaneous lymphoma obtained from a female BALB/c mouse. - + @@ -25251,7 +25251,7 @@ - + @@ -25265,7 +25265,7 @@ - + @@ -25279,7 +25279,7 @@ - + @@ -25293,7 +25293,7 @@ - + @@ -25307,7 +25307,7 @@ - + @@ -25315,7 +25315,7 @@ - + @@ -25335,7 +25335,7 @@ - + @@ -25343,7 +25343,7 @@ - + @@ -25363,7 +25363,7 @@ - + @@ -25377,7 +25377,7 @@ - + @@ -25399,7 +25399,7 @@ The Ba/F3-mpI cell line was established by introduction of the cDNA encoding the entire cMpI receptor into the IL-3 dependent murine lymphobiastoid cell line Ba/F3. - + @@ -25415,7 +25415,7 @@ An immortalized murine bone marrow-derived pro-B-cell line. - + @@ -25423,7 +25423,7 @@ - + @@ -25449,7 +25449,7 @@ - + @@ -25457,7 +25457,7 @@ - + @@ -25465,7 +25465,7 @@ - + @@ -25473,7 +25473,7 @@ - + @@ -25511,7 +25511,7 @@ - + @@ -25519,7 +25519,7 @@ - + @@ -25527,7 +25527,7 @@ - + @@ -25553,7 +25553,7 @@ - + @@ -25603,7 +25603,7 @@ - + @@ -25611,7 +25611,7 @@ - + @@ -25637,7 +25637,7 @@ - + @@ -25645,7 +25645,7 @@ - + @@ -25659,7 +25659,7 @@ - + @@ -25667,7 +25667,7 @@ - + @@ -25681,7 +25681,7 @@ - + @@ -25695,7 +25695,7 @@ - + @@ -25715,7 +25715,7 @@ - + @@ -25729,7 +25729,7 @@ - + @@ -25737,7 +25737,7 @@ - + @@ -25751,7 +25751,7 @@ - + @@ -25765,7 +25765,7 @@ - + @@ -25779,7 +25779,7 @@ - + @@ -25799,7 +25799,7 @@ - + @@ -25813,7 +25813,7 @@ - + @@ -25833,7 +25833,7 @@ - + @@ -25847,7 +25847,7 @@ - + @@ -25861,7 +25861,7 @@ - + @@ -25881,7 +25881,7 @@ - + @@ -25895,7 +25895,7 @@ - + @@ -25911,7 +25911,7 @@ The CAD cell line is a variant of a CNS-derived Cath.a cell line - + @@ -25931,7 +25931,7 @@ - + @@ -25951,7 +25951,7 @@ - + @@ -25971,7 +25971,7 @@ - + @@ -25985,7 +25985,7 @@ - + @@ -25999,7 +25999,7 @@ - + @@ -26019,7 +26019,7 @@ - + @@ -26039,7 +26039,7 @@ - + @@ -26059,7 +26059,7 @@ - + @@ -26079,7 +26079,7 @@ - + @@ -26095,7 +26095,7 @@ CEM cells are a line of lymphoblastic cells originally derived from a child with acute lymphoblastic leukemia. Like all uncloned cell lines, the original CEM cells are a mixed population of clones with varied genotypes and phenotypes. - + @@ -26105,7 +26105,7 @@ glucocorticoid resistant clone of CEM - + @@ -26113,7 +26113,7 @@ - + @@ -26121,7 +26121,7 @@ - + @@ -26131,7 +26131,7 @@ glucocorticoid sensitive clone of CEM - + @@ -26139,7 +26139,7 @@ - + @@ -26149,7 +26149,7 @@ HAT sensitive derivative of CEM obtained by treatment with 8-azaguanine - + @@ -26169,7 +26169,7 @@ - + @@ -26189,7 +26189,7 @@ - + @@ -26209,7 +26209,7 @@ - + @@ -26229,7 +26229,7 @@ - + @@ -26249,7 +26249,7 @@ - + @@ -26269,7 +26269,7 @@ - + @@ -26289,7 +26289,7 @@ - + @@ -26309,7 +26309,7 @@ - + @@ -26323,7 +26323,7 @@ - + @@ -26343,7 +26343,7 @@ - + @@ -26351,7 +26351,7 @@ - + @@ -26359,7 +26359,7 @@ - + @@ -26367,7 +26367,7 @@ - + @@ -26375,7 +26375,7 @@ - + @@ -26383,7 +26383,7 @@ - + @@ -26391,7 +26391,7 @@ - + @@ -26417,7 +26417,7 @@ - + @@ -26425,7 +26425,7 @@ - + @@ -26445,7 +26445,7 @@ - + @@ -26453,7 +26453,7 @@ - + @@ -26479,7 +26479,7 @@ - + @@ -26487,7 +26487,7 @@ - + @@ -26501,7 +26501,7 @@ - + @@ -26539,7 +26539,7 @@ - + @@ -26553,7 +26553,7 @@ - + @@ -26573,7 +26573,7 @@ - + @@ -26695,7 +26695,7 @@ - + @@ -26817,7 +26817,7 @@ - + @@ -26825,7 +26825,7 @@ - + @@ -26833,7 +26833,7 @@ - + @@ -26853,7 +26853,7 @@ - + @@ -26879,7 +26879,7 @@ - + @@ -26887,7 +26887,7 @@ - + @@ -26901,7 +26901,7 @@ - + @@ -26915,7 +26915,7 @@ - + @@ -26935,7 +26935,7 @@ - + @@ -26955,7 +26955,7 @@ - + @@ -26975,7 +26975,7 @@ - + @@ -26995,7 +26995,7 @@ - + @@ -27003,7 +27003,7 @@ - + @@ -27011,7 +27011,7 @@ - + @@ -27019,7 +27019,7 @@ - + @@ -27027,7 +27027,7 @@ - + @@ -27035,7 +27035,7 @@ - + @@ -27043,7 +27043,7 @@ - + @@ -27051,7 +27051,7 @@ - + @@ -27071,7 +27071,7 @@ - + @@ -27097,7 +27097,7 @@ - + @@ -27111,7 +27111,7 @@ - + @@ -27125,7 +27125,7 @@ - + @@ -27133,7 +27133,7 @@ - + @@ -27141,7 +27141,7 @@ - + @@ -27149,7 +27149,7 @@ - + @@ -27169,7 +27169,7 @@ - + @@ -27189,7 +27189,7 @@ - + @@ -27203,7 +27203,7 @@ - + @@ -27217,7 +27217,7 @@ - + @@ -27237,7 +27237,7 @@ - + @@ -27245,7 +27245,7 @@ - + @@ -27253,7 +27253,7 @@ - + @@ -27273,7 +27273,7 @@ - + @@ -27287,7 +27287,7 @@ - + @@ -27307,7 +27307,7 @@ - + @@ -27327,7 +27327,7 @@ - + @@ -27347,7 +27347,7 @@ - + @@ -27367,7 +27367,7 @@ - + @@ -27381,7 +27381,7 @@ - + @@ -27401,7 +27401,7 @@ - + @@ -27415,7 +27415,7 @@ - + @@ -27429,7 +27429,7 @@ - + @@ -27443,7 +27443,7 @@ - + @@ -27463,7 +27463,7 @@ - + @@ -27479,7 +27479,7 @@ GP8 cells were isolated from rat brain cortex and immortalized with SV40 large T Ag - + @@ -27493,7 +27493,7 @@ - + @@ -27501,7 +27501,7 @@ - + @@ -27509,7 +27509,7 @@ - + @@ -27517,7 +27517,7 @@ - + @@ -27525,7 +27525,7 @@ - + @@ -27563,7 +27563,7 @@ - + @@ -27583,7 +27583,7 @@ - + @@ -27591,7 +27591,7 @@ - + @@ -27611,7 +27611,7 @@ - + @@ -27631,7 +27631,7 @@ - + @@ -27651,7 +27651,7 @@ - + @@ -27665,7 +27665,7 @@ - + @@ -27681,7 +27681,7 @@ HBE1 cell line is an immortalized line of normal human airway epithelial cells - + @@ -27695,7 +27695,7 @@ - + @@ -27715,7 +27715,7 @@ - + @@ -27735,7 +27735,7 @@ - + @@ -27755,7 +27755,7 @@ - + @@ -27775,7 +27775,7 @@ - + @@ -27795,7 +27795,7 @@ - + @@ -27809,7 +27809,7 @@ - + @@ -27823,7 +27823,7 @@ - + @@ -27843,7 +27843,7 @@ - + @@ -27857,7 +27857,7 @@ - + @@ -27873,7 +27873,7 @@ An immortalized proximal tubule epithelial cell line from normal adult human kidney. - + @@ -27893,7 +27893,7 @@ - + @@ -27913,7 +27913,7 @@ - + @@ -27933,7 +27933,7 @@ - + @@ -27953,7 +27953,7 @@ - + @@ -27973,7 +27973,7 @@ - + @@ -27987,7 +27987,7 @@ - + @@ -28001,7 +28001,7 @@ - + @@ -28021,7 +28021,7 @@ - + @@ -28041,7 +28041,7 @@ - + @@ -28061,7 +28061,7 @@ - + @@ -28081,7 +28081,7 @@ - + @@ -28095,7 +28095,7 @@ - + @@ -28111,7 +28111,7 @@ The HT22 nerve cell line is a subclone of HT4, derived from the mouse hippocampus. - + @@ -28131,7 +28131,7 @@ - + @@ -28151,7 +28151,7 @@ - + @@ -28171,7 +28171,7 @@ - + @@ -28179,7 +28179,7 @@ - + @@ -28193,7 +28193,7 @@ - + @@ -28213,7 +28213,7 @@ - + @@ -28233,7 +28233,7 @@ - + @@ -28253,7 +28253,7 @@ - + @@ -28273,7 +28273,7 @@ - + @@ -28293,7 +28293,7 @@ - + @@ -28415,7 +28415,7 @@ - + @@ -28423,7 +28423,7 @@ - + @@ -28443,7 +28443,7 @@ - + @@ -28463,7 +28463,7 @@ - + @@ -28483,7 +28483,7 @@ - + @@ -28503,7 +28503,7 @@ - + @@ -28523,7 +28523,7 @@ - + @@ -28543,7 +28543,7 @@ - + @@ -28557,7 +28557,7 @@ - + @@ -28577,7 +28577,7 @@ - + @@ -28591,7 +28591,7 @@ - + @@ -28605,7 +28605,7 @@ - + @@ -28619,7 +28619,7 @@ - + @@ -28639,7 +28639,7 @@ - + @@ -28659,7 +28659,7 @@ - + @@ -28673,7 +28673,7 @@ - + @@ -28693,7 +28693,7 @@ - + @@ -28713,7 +28713,7 @@ - + @@ -28727,7 +28727,7 @@ - + @@ -28747,7 +28747,7 @@ - + @@ -28779,7 +28779,7 @@ - + @@ -28787,7 +28787,7 @@ - + @@ -28819,7 +28819,7 @@ - + @@ -28827,7 +28827,7 @@ - + @@ -28841,7 +28841,7 @@ - + @@ -28861,7 +28861,7 @@ - + @@ -28881,7 +28881,7 @@ - + @@ -28901,7 +28901,7 @@ - + @@ -28921,7 +28921,7 @@ - + @@ -28941,7 +28941,7 @@ - + @@ -28961,7 +28961,7 @@ - + @@ -28981,7 +28981,7 @@ - + @@ -29001,7 +29001,7 @@ - + @@ -29015,7 +29015,7 @@ - + @@ -29035,7 +29035,7 @@ - + @@ -29055,7 +29055,7 @@ - + @@ -29075,7 +29075,7 @@ - + @@ -29091,7 +29091,7 @@ This human stromal cell line was obtained from adherent bone marrow cell layers of Dexter-type long-term BMC (bone marrow culture) after immortalisation with SV40. - + @@ -29113,7 +29113,7 @@ H4IIEC3 subclone - + @@ -29133,7 +29133,7 @@ - + @@ -29153,7 +29153,7 @@ - + @@ -29173,7 +29173,7 @@ - + @@ -29217,7 +29217,7 @@ - + @@ -29225,7 +29225,7 @@ - + @@ -29233,7 +29233,7 @@ - + @@ -29247,7 +29247,7 @@ - + @@ -29261,7 +29261,7 @@ - + @@ -29281,7 +29281,7 @@ - + @@ -29301,7 +29301,7 @@ - + @@ -29321,7 +29321,7 @@ - + @@ -29341,7 +29341,7 @@ - + @@ -29361,7 +29361,7 @@ - + @@ -29381,7 +29381,7 @@ - + @@ -29389,7 +29389,7 @@ - + @@ -29397,7 +29397,7 @@ - + @@ -29405,7 +29405,7 @@ - + @@ -29551,7 +29551,7 @@ - + @@ -29559,7 +29559,7 @@ - + @@ -29567,7 +29567,7 @@ - + @@ -29575,7 +29575,7 @@ - + @@ -29595,7 +29595,7 @@ - + @@ -29609,7 +29609,7 @@ - + @@ -29617,7 +29617,7 @@ - + @@ -29643,7 +29643,7 @@ - + @@ -29663,7 +29663,7 @@ - + @@ -29683,7 +29683,7 @@ - + @@ -29703,7 +29703,7 @@ - + @@ -29723,7 +29723,7 @@ - + @@ -29737,7 +29737,7 @@ - + @@ -29757,7 +29757,7 @@ - + @@ -29777,7 +29777,7 @@ - + @@ -29791,7 +29791,7 @@ - + @@ -29799,7 +29799,7 @@ - + @@ -29807,7 +29807,7 @@ - + @@ -29887,7 +29887,7 @@ - + @@ -29895,7 +29895,7 @@ - + @@ -29903,7 +29903,7 @@ - + @@ -29911,7 +29911,7 @@ - + @@ -29919,7 +29919,7 @@ - + @@ -29927,7 +29927,7 @@ - + @@ -29941,7 +29941,7 @@ - + @@ -29955,7 +29955,7 @@ - + @@ -29969,7 +29969,7 @@ - + @@ -29977,7 +29977,7 @@ - + @@ -29985,7 +29985,7 @@ - + @@ -29993,7 +29993,7 @@ - + @@ -30013,7 +30013,7 @@ - + @@ -30057,7 +30057,7 @@ - + @@ -30065,7 +30065,7 @@ - + @@ -30073,7 +30073,7 @@ - + @@ -30081,7 +30081,7 @@ - + @@ -30089,7 +30089,7 @@ - + @@ -30097,7 +30097,7 @@ - + @@ -30105,7 +30105,7 @@ - + @@ -30119,7 +30119,7 @@ - + @@ -30127,7 +30127,7 @@ - + @@ -30153,7 +30153,7 @@ - + @@ -30161,7 +30161,7 @@ - + @@ -30199,7 +30199,7 @@ - + @@ -30243,7 +30243,7 @@ - + @@ -30263,7 +30263,7 @@ - + @@ -30367,7 +30367,7 @@ - + @@ -30381,7 +30381,7 @@ - + @@ -30461,7 +30461,7 @@ - + @@ -30469,7 +30469,7 @@ - + @@ -30477,7 +30477,7 @@ - + @@ -30485,7 +30485,7 @@ - + @@ -30493,7 +30493,7 @@ - + @@ -30501,7 +30501,7 @@ - + @@ -30509,7 +30509,7 @@ - + @@ -30553,7 +30553,7 @@ - + @@ -30579,7 +30579,7 @@ - + @@ -30593,7 +30593,7 @@ - + @@ -30601,7 +30601,7 @@ - + @@ -30621,7 +30621,7 @@ - + @@ -30629,7 +30629,7 @@ - + @@ -30637,7 +30637,7 @@ - + @@ -30669,7 +30669,7 @@ - + @@ -30695,7 +30695,7 @@ - + @@ -30709,7 +30709,7 @@ - + @@ -30725,7 +30725,7 @@ RBE4 cells were isolated from rat brain cortex and immortalized with the plasmid pE1A-neo, containing the adenovirus E1A-encoding sequence followed by a neomycin resistance gene. - + @@ -30739,7 +30739,7 @@ - + @@ -30747,7 +30747,7 @@ - + @@ -30755,7 +30755,7 @@ - + @@ -30763,7 +30763,7 @@ - + @@ -30777,7 +30777,7 @@ - + @@ -30791,7 +30791,7 @@ - + @@ -30799,7 +30799,7 @@ - + @@ -30813,7 +30813,7 @@ - + @@ -30833,7 +30833,7 @@ - + @@ -30853,7 +30853,7 @@ - + @@ -30873,7 +30873,7 @@ - + @@ -30893,7 +30893,7 @@ - + @@ -30913,7 +30913,7 @@ - + @@ -30921,7 +30921,7 @@ - + @@ -30929,7 +30929,7 @@ - + @@ -30961,7 +30961,7 @@ - + @@ -30969,7 +30969,7 @@ - + @@ -31073,7 +31073,7 @@ - + @@ -31087,7 +31087,7 @@ - + @@ -31107,7 +31107,7 @@ - + @@ -31121,7 +31121,7 @@ - + @@ -31129,7 +31129,7 @@ - + @@ -31143,7 +31143,7 @@ - + @@ -31157,7 +31157,7 @@ - + @@ -31207,7 +31207,7 @@ - + @@ -31257,7 +31257,7 @@ - + @@ -31295,7 +31295,7 @@ - + @@ -31303,7 +31303,7 @@ - + @@ -31311,7 +31311,7 @@ - + @@ -31331,7 +31331,7 @@ - + @@ -31345,7 +31345,7 @@ - + @@ -31359,7 +31359,7 @@ - + @@ -31367,7 +31367,7 @@ - + @@ -31387,7 +31387,7 @@ - + @@ -31395,7 +31395,7 @@ - + @@ -31409,7 +31409,7 @@ - + @@ -31423,7 +31423,7 @@ - + @@ -31431,7 +31431,7 @@ - + @@ -31463,7 +31463,7 @@ - + @@ -31489,7 +31489,7 @@ - + @@ -31503,7 +31503,7 @@ - + @@ -31523,7 +31523,7 @@ - + @@ -31537,7 +31537,7 @@ - + @@ -31545,7 +31545,7 @@ - + @@ -31559,7 +31559,7 @@ - + @@ -31573,7 +31573,7 @@ - + @@ -31581,7 +31581,7 @@ - + @@ -31589,7 +31589,7 @@ - + @@ -31597,7 +31597,7 @@ - + @@ -31605,7 +31605,7 @@ - + @@ -31625,7 +31625,7 @@ - + @@ -31633,7 +31633,7 @@ - + @@ -31641,7 +31641,7 @@ - + @@ -31649,7 +31649,7 @@ - + @@ -31669,7 +31669,7 @@ - + @@ -31689,7 +31689,7 @@ - + @@ -31709,7 +31709,7 @@ - + @@ -31723,10 +31723,10 @@ - - - From 9649a3a2ee99c9eef0749541f6b9f7c3987914ec Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 27 Jan 2026 23:04:12 -0800 Subject: [PATCH 037/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b269938f9..8bf568f07 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 326eb26687f7307b6ae7e6b8f2e215057606180e + revision: e0109a9ea9b0e0119c3e5cd19146514c2282fab0 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: ae232f1179efccad72f6d8284a539c7c8f818175 + revision: 34bf94937b07b4d27158f2c1f1693dd6bf18131b branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) From a162678c7ed78842d56f700977d522d2d32172b0 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 09:08:24 -0800 Subject: [PATCH 038/173] added code to disable security for test after_all calls --- test/test_case.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/test_case.rb b/test/test_case.rb index f68c32b77..1589e3ce2 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -109,6 +109,7 @@ def before_all end def after_all + self.class.disable_security after_suite super end @@ -209,7 +210,11 @@ def self.enable_security LinkedData.settings.enable_security = true end - def self.reset_security(old_security = @@old_security_setting) + def self.disable_security + LinkedData.settings.enable_security = false + end + + def self.reset_security(old_security = @@old_security_setting) LinkedData.settings.enable_security = old_security end From 8638245a35c08b3f26acfc706c00ba7a99826290 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 11:10:32 -0800 Subject: [PATCH 039/173] added a safeguard to disable security if test that uses it fails --- .../test_search_models_controller.rb | 80 +++++++++---------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index ea741ee32..a6e24bb25 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -18,7 +18,7 @@ def test_show_all_collection get '/admin/search/collections' assert last_response.ok? res = MultiJson.load(last_response.body) - array = %w[agents_metadata ontology_data ontology_metadata prop_search_core1 term_search_core1] + array = %w[ontology_data ontology_metadata prop_search_core1 term_search_core1] assert_equal res["collections"].sort , array.sort end @@ -38,7 +38,6 @@ def test_collection_schema end def test_collection_search - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ process_submission: false, acronym: "BROSEARCHTEST", @@ -78,54 +77,66 @@ def test_search_security submission_count: 1 }) - subs = LinkedData::Models::OntologySubmission.all + subs.each do |s| s.bring_remaining s.index_all(Logger.new($stdout)) end + allowed_user1 = User.new({ + username: "allowed1", + email: "test1@example.org", + password: "12345" + }) + allowed_user1.save + + allowed_user2 = User.new({ + username: "allowed2", + email: "test2@example.org", + password: "12345" + }) + allowed_user2.save - allowed_user = User.new({ - username: "allowed", - email: "test1@example.org", - password: "12345" - }) - allowed_user.save blocked_user = User.new({ username: "blocked", - email: "test2@example.org", + email: "test3@example.org", password: "12345" }) blocked_user.save bro = bro.first bro.bring_remaining - bro.acl = [allowed_user] + bro.acl = [allowed_user1, allowed_user2] bro.viewingRestriction = "private" bro.save - self.class.enable_security - get "/search/ontologies?query=#{bro.acronym}&apikey=#{blocked_user.apikey}" - response = MultiJson.load(last_response.body)["collection"] - assert_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} + begin + self.class.enable_security - get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{blocked_user.apikey}" - assert last_response.ok? - res = MultiJson.load(last_response.body) - assert_equal 0, res['totalCount'] + get "/search/ontologies?query=\"#{bro.acronym}\"&apikey=#{blocked_user.apikey}" + response = MultiJson.load(last_response.body)["collection"] + assert_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} - get "/search/ontologies?query=#{bro.acronym}&apikey=#{allowed_user.apikey}" - response = MultiJson.load(last_response.body)["collection"] - refute_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} + get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{blocked_user.apikey}" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal 0, res['totalCount'] - get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{allowed_user.apikey}" - assert last_response.ok? - res = MultiJson.load(last_response.body) - assert_equal 1, res['totalCount'] + get "/search/ontologies?query=\"#{bro.acronym}\"&apikey=#{allowed_user1.apikey}" + response = MultiJson.load(last_response.body)["collection"] + refute_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} - self.class.reset_security(false) + get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{allowed_user1.apikey}" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal 1, res['totalCount'] + + self.class.reset_security(false) + ensure + self.class.disable_security + end end def test_ontology_metadata_search @@ -231,7 +242,6 @@ def test_ontology_metadata_search def test_ontology_metadata_filters num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: 10, submission_count: 1) - group1 = LinkedData::Models::Group.find('group-1').first || LinkedData::Models::Group.new(acronym: 'group-1', name: "Test Group 1").save group2 = LinkedData::Models::Group.find('group-2').first || LinkedData::Models::Group.new(acronym: 'group-2', name: "Test Group 2").save category1 = LinkedData::Models::Category.find('category-1').first || LinkedData::Models::Category.new(acronym: 'category-1', name: "Test Category 1").save @@ -251,7 +261,6 @@ def test_ontology_metadata_filters o.save end - # test filter by group and category get "/search/ontologies?page=1&pagesize=100&groups=#{group1.acronym}" assert last_response.ok? @@ -260,7 +269,6 @@ def test_ontology_metadata_filters assert last_response.ok? assert_equal ontologies2.size, MultiJson.load(last_response.body)["collection"].length - get "/search/ontologies?page=1&pagesize=100&groups=#{group1.acronym},#{group2.acronym}" assert last_response.ok? assert_equal ontologies1.size + ontologies2.size, MultiJson.load(last_response.body)["collection"].length @@ -284,8 +292,6 @@ def test_ontology_metadata_filters assert last_response.ok? assert_equal ontologies2.size, MultiJson.load(last_response.body)["collection"].length - - ontologies3 = ontologies[9] ontologies3.bring_remaining ontologies3.group = [group1, group2] @@ -312,7 +318,6 @@ def test_ontology_metadata_filters get "/search/ontologies?page=1&pagesize=100&q=tes&sort=creationDate_dt desc" - assert last_response.ok? submissions = MultiJson.load(last_response.body) refute_empty submissions["collection"] @@ -327,15 +332,12 @@ def test_ontology_metadata_filters refute_empty submissions["collection"] assert_equal 1, submissions["collection"].size - - get "/search/ontologies?page=1&pagesize=100&q=tes&hasOntologyLanguage=OWL" assert last_response.ok? submissions = MultiJson.load(last_response.body) refute_empty submissions["collection"] assert_equal ontologies.size-1 , submissions["collection"].size - # test ontology filter with submission filter attributes get "/search/ontologies?page=1&pagesize=100&q=tes&groups=group-2&hasDomain=category-2&hasOntologyLanguage=OWL" assert last_response.ok? @@ -343,10 +345,7 @@ def test_ontology_metadata_filters refute_empty submissions["collection"] assert_equal ontologies2.size + 1 , submissions["collection"].size - - # test ontology filter with status - get "/search/ontologies?page=1&pagesize=100&status=retired" assert last_response.ok? submissions = MultiJson.load(last_response.body) @@ -403,7 +402,6 @@ def test_search_data # res = MultiJson.load(last_response.body) # assert_equal count.sum, res['totalCount'] - get "/search/ontologies/content?q=*&ontologies=MCCLSEARCHTEST-0,BROSEARCHTEST-0" assert last_response.ok? res = MultiJson.load(last_response.body) @@ -418,6 +416,6 @@ def test_search_data assert last_response.ok? res = MultiJson.load(last_response.body) assert_includes count, res['totalCount'] - end + end \ No newline at end of file From 8768093bdcb3f397ffc5684b8b09d003f7d1bb05 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 12:23:20 -0800 Subject: [PATCH 040/173] updated test_rack_attack to Rackup --- test/middleware/test_rack_attack.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/middleware/test_rack_attack.rb b/test/middleware/test_rack_attack.rb index 92b4d6369..540f8a983 100644 --- a/test/middleware/test_rack_attack.rb +++ b/test/middleware/test_rack_attack.rb @@ -5,7 +5,7 @@ RACK_CONFIG = File.join([settings.root, "config.ru"]) class TestRackAttack < TestCase - + def before_suite # Store app settings @@auth_setting = LinkedData.settings.enable_security @@ -40,7 +40,7 @@ def before_suite # Fork the process to create two servers. This isolates the Rack::Attack configuration, which makes other tests fail if included. @@pid1 = fork do require_relative '../../config/rack_attack' - Rack::Server.start( + Rackup::Server.start( config: RACK_CONFIG, Port: @@port1 ) @@ -50,7 +50,7 @@ def before_suite @@port2 = unused_port @@pid2 = fork do require_relative '../../config/rack_attack' - Rack::Server.start( + Rackup::Server.start( config: RACK_CONFIG, Port: @@port2 ) @@ -90,7 +90,7 @@ def test_throttling_limit # TODO: Upgrading rack-attack from 5 to 6 causes this test to fail with a 500 Internal Server error. # Project is currently pinned at 5.4.2. Investigate failure at the time we decide to upgrade. def test_throttling_limit_with_forwarding - limit = LinkedData::OntologiesAPI.settings.req_per_second_per_ip + limit = LinkedData::OntologiesAPI.settings.req_per_second_per_ip headers = {"Authorization" => "apikey token=#{@@user.apikey}", "X-Forwarded-For" => "1.2.3.6"} exception = assert_raises(OpenURI::HTTPError) do From fad1d19d5401b65230894c27d9bfa99b54d8ae19 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 12:31:46 -0800 Subject: [PATCH 041/173] search_helper improved language handling; metadata search options --- helpers/search_helper.rb | 288 ++++++++++++++++++++++++++++++++------- 1 file changed, 237 insertions(+), 51 deletions(-) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index 80eec4cc2..e0b7ed542 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -19,7 +19,6 @@ module SearchHelper VALUESET_ROOTS_ONLY_PARAM = "valueset_roots_only" VALUESET_EXCLUDE_ROOTS_PARAM = "valueset_exclude_roots" ONTOLOGY_TYPES_PARAM = "ontology_types" - LANGUAGES_PARAM = "lang" ALSO_SEARCH_VIEWS = "also_search_views" # NCBO-961 MATCH_HTML_PRE = "" @@ -27,10 +26,8 @@ module SearchHelper MATCH_TYPE_PREFLABEL = "prefLabel" MATCH_TYPE_SYNONYM = "synonym" MATCH_TYPE_PROPERTY = "property" - MATCH_TYPE_DEFINITION = "definition" MATCH_TYPE_LABEL = "label" MATCH_TYPE_LABELGENERATED = "labelGenerated" - NO_LANGUAGE_SUFFIX = "none" MATCH_TYPE_MAP = { "resource_id" => "id", @@ -87,10 +84,6 @@ def get_term_search_query(text, params={}) end end - lang = params["lang"] || params["language"] - lang_suffix = lang && !lang.eql?("all") ? "_#{lang}" : "" - - query = "" params["defType"] = "edismax" params["stopwords"] = "true" params["lowercaseOperators"] = "true" @@ -102,29 +95,53 @@ def get_term_search_query(text, params={}) params["hl.simple.pre"] = MATCH_HTML_PRE params["hl.simple.post"] = MATCH_HTML_POST - # text.gsub!(/\*+$/, '') - if params[EXACT_MATCH_PARAM] == "true" query = "\"#{solr_escape(text)}\"" - params["qf"] = "resource_id^20 notation^20 oboId^20 prefLabelExact#{lang_suffix}^10 synonymExact#{lang_suffix} #{QUERYLESS_FIELDS_STR_NO_IDS}" - params["hl.fl"] = "resource_id prefLabelExact#{lang_suffix} synonymExact#{lang_suffix} #{QUERYLESS_FIELDS_STR}" + params["qf"] = "resource_id^20 #{add_lang_suffix('prefLabel', '^10')} #{add_lang_suffix('synonymExact')} #{QUERYLESS_FIELDS_STR}" + params["hl.fl"] = "resource_id #{add_lang_suffix('prefLabelExact')} #{add_lang_suffix('synonymExact')} #{QUERYLESS_FIELDS_STR}" elsif params[SUGGEST_PARAM] == "true" || text[-1] == '*' text.gsub!(/\*+$/, '') query = "\"#{solr_escape(text)}\"" params["qt"] = "/suggest_ncbo" - params["qf"] = " prefLabelExact#{lang_suffix}^100 prefLabelSuggestEdge#{lang_suffix}^50 synonymSuggestEdge#{lang_suffix}^10 prefLabelSuggestNgram#{lang_suffix} synonymSuggestNgram#{lang_suffix} resource_id #{QUERYLESS_FIELDS_STR}" - params["pf"] = "prefLabelSuggest#{lang_suffix}^50" - params["hl.fl"] = "prefLabelExact#{lang_suffix} prefLabelSuggestEdge#{lang_suffix} synonymSuggestEdge#{lang_suffix} prefLabelSuggestNgram#{lang_suffix} synonymSuggestNgram#{lang_suffix} resource_id #{QUERYLESS_FIELDS_STR}" + params["qf"] = [ + add_lang_suffix('prefLabelExact', '^100'), + add_lang_suffix('prefLabelSuggestEdge', '^50'), + add_lang_suffix('synonymSuggestEdge', '^10'), + add_lang_suffix('prefLabelSuggestNgram'), + add_lang_suffix('synonymSuggestNgram'), + "resource_id #{QUERYLESS_FIELDS_STR}" + ].join(' ') + + params["pf"] = add_lang_suffix('prefLabelSuggest', '^50') + + params["hl.fl"] = [ + add_lang_suffix('prefLabelExact'), + add_lang_suffix('prefLabelSuggestEdge'), + add_lang_suffix('synonymSuggestEdge'), + add_lang_suffix('prefLabelSuggestNgram'), + add_lang_suffix('synonymSuggestNgram'), + "resource_id #{QUERYLESS_FIELDS_STR}" + ].join(' ') else if text.strip.empty? query = '*' else query = solr_escape(text) end - params["qf"] = "resource_id^100 notation^100 oboId^100 prefLabelExact#{lang_suffix}^90 prefLabel#{lang_suffix}^70 synonymExact#{lang_suffix}^50 synonym#{lang_suffix}^10 #{QUERYLESS_FIELDS_STR_NO_IDS}" + + params["qf"] = [ + "resource_id^100", + add_lang_suffix('prefLabelExact', '^90'), + add_lang_suffix('prefLabel', '^70'), + add_lang_suffix('synonymExact', '^50'), + add_lang_suffix('synonym', '^10'), + QUERYLESS_FIELDS_STR + ].join(' ') + params["qf"] << " property" if params[INCLUDE_PROPERTIES_PARAM] == "true" - params["bq"] = "idAcronymMatch:true^80" - params["hl.fl"] = "resource_id prefLabelExact#{lang_suffix} prefLabel#{lang_suffix} synonymExact#{lang_suffix} synonym#{lang_suffix} #{QUERYLESS_FIELDS_STR}" + + params["hl.fl"] = "resource_id #{add_lang_suffix('prefLabelExact')} #{ add_lang_suffix('prefLabel')} #{add_lang_suffix('synonymExact')} #{add_lang_suffix('synonym')} #{QUERYLESS_FIELDS_STR}" + params["hl.fl"] = "#{params["hl.fl"]} property" if params[INCLUDE_PROPERTIES_PARAM] == "true" end @@ -185,10 +202,6 @@ def get_term_search_query(text, params={}) params["fq"] = filter_query params["q"] = query - - # binding.pry - - query end @@ -230,6 +243,72 @@ def add_matched_fields(solr_response, default_match) solr_response["match_types"] = all_matches end + def portal_language + Goo.main_languages.first + end + + def request_languages + lang = params['lang'] || params['languages'] + + return [portal_language] if lang.blank? + + lang.split(',') + end + + def request_multiple_languages? + request_languages.size > 1 || request_all_languages? + end + + def request_languages? + !(params['lang'] || params['language']).blank? + end + + def request_all_languages? + request_languages.first.eql?('all') + end + + def add_lang_suffix(attr, rank = "") + if request_languages? && !request_all_languages? + languages = request_languages + languages.map { |lang| "#{attr}_#{lang}#{rank} " }.join + else + "#{attr}#{rank}" + end + end + + def pref_label_by_language(doc) + Array(doc["prefLabel_#{request_languages.first}".to_sym]).first || Array(doc["prefLabel_none".to_sym]).first || Array(doc[:prefLabel]).first + end + + def filter_attrs_by_language(doc) + lang_values = {} + doc.each do |k, v| + attr, lang = k.to_s.split('_') + + next if [:ontology_rank, :resource_id, :resource_model].include?(k) + next if lang.blank? || attr.blank? + next if !(request_languages + %w[none]).include?(lang) && !request_all_languages? + + lang_values[attr.to_sym] ||= {} + lang_values[attr.to_sym][lang] ||= [] + lang_values[attr.to_sym][lang] += v + end + + if request_multiple_languages? + lang_values.each do |k, lang_vals| + doc[k] = lang_vals + end + else + lang_values.each do |k, lang_vals| + doc[k] = lang_vals.map { |l, v| l.eql?('none') ? nil : v }.compact.flatten + Array(lang_vals['none']) + end + + doc[:prefLabel] = pref_label_by_language(doc) + end + + doc + end + # see https://github.com/rsolr/rsolr/issues/101 # and https://github.com/projecthydra/active_fedora/commit/75b4afb248ee61d9edb56911b2ef51f30f1ce17f # @@ -342,7 +421,7 @@ def populate_classes_from_search(classes, ontology_acronyms=nil) params["fq"] << " AND #{get_quoted_field_query_param(class_ids, "OR", "resource_id")}" params["rows"] = 99999 # Replace fake query with wildcard - resp = LinkedData::Models::Class.search("*:*", params) + resp = LinkedData::Models::Class.submit_search_query("*:*", params) classes_hash = {} resp["response"]["docs"].each do |doc| @@ -357,48 +436,155 @@ def populate_classes_from_search(classes, ontology_acronyms=nil) doc[:submission] = old_class.submission doc[:properties] = MultiJson.load(doc.delete(:propertyRaw)) if include_param_contains?(:properties) instance = LinkedData::Models::Class.read_only(doc) - filter_language_attributes(@params, instance) + instance.prefLabel = pref_label_by_language(doc) classes_hash[ont_uri_class_uri] = instance end classes_hash end - def filter_language_attribute(params, class_instance, attr, is_single) - if class_instance.respond_to?(attr) - lang_param = (params["lang"] || params["language"])&.downcase - lang_suffix = lang_param && !lang_param.eql?("all") ? "_#{lang_param}" : "" - - if !lang_suffix.empty? && class_instance.respond_to?("#{attr}#{lang_suffix}") - class_instance[attr] = is_single ? class_instance["#{attr}#{lang_suffix}"][0] : class_instance["#{attr}#{lang_suffix}"] - elsif !lang_param.eql?("all") - site_label = Goo.main_languages[0] - - if class_instance.respond_to?("#{attr}_#{site_label}") && class_instance["#{attr}_#{site_label}"] - class_instance[attr] = is_single ? class_instance["#{attr}_#{site_label}"][0] : class_instance["#{attr}_#{site_label}"] - elsif class_instance.respond_to?("#{attr}_#{NO_LANGUAGE_SUFFIX}") && class_instance["#{attr}_#{NO_LANGUAGE_SUFFIX}"] - class_instance[attr] = is_single ? class_instance["#{attr}_#{NO_LANGUAGE_SUFFIX}"][0] : class_instance["#{attr}_#{NO_LANGUAGE_SUFFIX}"] - elsif is_single - class_instance[attr] = class_instance[attr][0] - end - end - end - end - - def filter_language_attributes(params, class_instance) - filter_language_attribute(params, class_instance, MATCH_TYPE_PREFLABEL, true) - filter_language_attribute(params, class_instance, MATCH_TYPE_SYNONYM, false) - filter_language_attribute(params, class_instance, MATCH_TYPE_DEFINITION, false) - end - def validate_params_solr_population(allowed_includes_params) leftover = includes_param - allowed_includes_params invalid = leftover.length > 0 message = "The `include` query string parameter cannot accept #{leftover.join(", ")}, please use only #{allowed_includes_params.join(", ")}" error 400, message if invalid end + + def get_ontology_metadata_search_options(params) + groups = params.fetch("groups", "").split(',') + categories = params.fetch("hasDomain", "").split(',') + languages = params.fetch("languages", "").split(',') + status = params.fetch("status", "").split(',') + format = params.fetch("hasOntologyLanguage", "").split(',') + is_of_type = params.fetch("isOfType", "").split(',') + has_format = params.fetch("hasFormat", "").split(',') + visibility = params["visibility"] + show_views = params["show_views"] == 'true' + sort = params.fetch("sort", "score desc, ontology_name_sort asc, ontology_acronym_sort asc") + page, page_size = page_params + + fq = [ + 'resource_model:"ontology_submission"', + 'submissionStatus_txt:ERROR_* OR submissionStatus_txt:"RDF" OR submissionStatus_txt:"UPLOADED"', + groups.map { |x| "ontology_group_txt:\"http://data.bioontology.org/groups/#{x.upcase}\"" }.join(' OR '), + categories.map { |x| "ontology_hasDomain_txt:\"http://data.bioontology.org/categories/#{x.upcase}\"" }.join(' OR '), + languages.map { |x| "naturalLanguage_txt:\"#{x.downcase}\"" }.join(' OR '), + ] + + fq << "ontology_viewingRestriction_t:#{visibility}" unless visibility.blank? + fq << "!ontology_viewOf_t:*" unless show_views + + fq << format.map { |x| "hasOntologyLanguage_t:\"http://data.bioontology.org/ontology_formats/#{x}\"" }.join(' OR ') unless format.blank? + + fq << status.map { |x| "status_t:#{x}" }.join(' OR ') unless status.blank? + fq << is_of_type.map { |x| "isOfType_t:#{x}" }.join(' OR ') unless is_of_type.blank? + fq << has_format.map { |x| "hasFormalityLevel_t:#{x}" }.join(' OR ') unless has_format.blank? + + fq.reject!(&:blank?) + + if params[:qf] + qf = params[:qf] + else + qf = [ + "ontologySuggestEdge^25 ontology_acronymSuggestEdge^25 ontology_nameSuggestEdge^15 descriptionSuggestEdge^10 ", # start of the word first + "ontology_t^15 ontology_acronym_text^15 ontology_name_text^10 description_text^5 ", # full word match + "ontologySuggestNgram^2 ontology_acronymSuggestNgram^2 ontology_nameSuggestNgram^1.5 descriptionSuggestNgram" # substring match last + ].join(' ') + end + + options = { + fq: fq, + qf: qf, + page: page, + page_size: page_size, + sort: sort + } + options + end + + def get_query(params) + if params[:query].nil? && params[:q].nil? + raise error 400, "The search query must be provided via /search?q=[&page=&pagesize=] /search?query=[&page=&pagesize=]" + end + query = params[:query] || params[:q] + query + end + + def search(model, query, params = {}) + query = query.blank? ? "*" : query + resp = model.search(query, search_params(**params)) + total_found = resp["response"]["numFound"] + docs = resp["response"]["docs"] + + page_object(docs, total_found) + end + + def search_params(defType: "edismax", fq:, qf:, stopwords: "true", lowercaseOperators: "true", page:, page_size:, fl: '*,score', sort:) + { + defType: defType, + fq: fq, + qf: qf, + sort: sort, + start: (page - 1) * page_size, + rows: page_size, + fl: fl, + stopwords: stopwords, + lowercaseOperators: lowercaseOperators, + } + end + + def process_search(params = nil) + params ||= @params + params['q'] ||= params['query'] + params.delete('query') + text = params["q"] + + query = get_term_search_query(text, params) + # puts "Edismax query: #{query}, params: #{params}" + set_page_params(params) + + docs = Array.new + resp = LinkedData::Models::Class.search(query, params) + total_found = resp["response"]["numFound"] + add_matched_fields(resp, Sinatra::Helpers::SearchHelper::MATCH_TYPE_PREFLABEL) + ontology_rank = LinkedData::Models::Ontology.rank + + resp["response"]["docs"].each do |doc| + doc = doc.symbolize_keys + # NCBO-974 + doc[:matchType] = resp["match_types"][doc[:id]] + resource_id = doc[:resource_id] + doc.delete :resource_id + doc[:id] = resource_id + # TODO: The `rescue next` on the following line shouldn't be here + # However, at some point we didn't store the ontologyId in the index + # and these records haven't been cleared out so this is getting skipped + ontology_uri = doc[:ontologyId].sub(/\/submissions\/.*/, "") rescue next + ontology = LinkedData::Models::Ontology.read_only(id: ontology_uri, acronym: doc[:submissionAcronym]) + submission = LinkedData::Models::OntologySubmission.read_only(id: doc[:ontologyId], ontology: ontology) + doc[:submission] = submission + doc[:ontology_rank] = (ontology_rank[doc[:submissionAcronym]] && !ontology_rank[doc[:submissionAcronym]].empty?) ? ontology_rank[doc[:submissionAcronym]][:normalizedScore] : 0.0 + doc[:properties] = MultiJson.load(doc.delete(:propertyRaw)) if include_param_contains?(:properties) + + doc = filter_attrs_by_language(doc) + + instance = doc[:provisional] ? LinkedData::Models::ProvisionalClass.read_only(doc) : LinkedData::Models::Class.read_only(doc) + docs.push(instance) + end + + unless params['sort'] + if !text.nil? && text[-1] == '*' + docs.sort! { |a, b| [b[:score], a[:prefLabelExact].downcase, b[:ontology_rank]] <=> [a[:score], b[:prefLabelExact].downcase, a[:ontology_rank]] } + else + docs.sort! { |a, b| [b[:score], b[:ontology_rank]] <=> [a[:score], a[:ontology_rank]] } + end + end + + page_object(docs, total_found) + end + end end end -helpers Sinatra::Helpers::SearchHelper +helpers Sinatra::Helpers::SearchHelper \ No newline at end of file From f711f822e0f2aa4caff8e2229043a3f3d902b1a2 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 12:54:53 -0800 Subject: [PATCH 042/173] Gemfile.lock udpate --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8bf568f07..bac68a276 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 34bf94937b07b4d27158f2c1f1693dd6bf18131b + revision: 5c84a23b51efe4a757683071dcd0559c674252bc branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) From daf70633f62d21d39d74a5b73d8f3144824d9887 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 13:09:05 -0800 Subject: [PATCH 043/173] added endpoints for ontologies and content searches --- controllers/search_controller.rb | 131 ++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 47 deletions(-) diff --git a/controllers/search_controller.rb b/controllers/search_controller.rb index 280944a6b..88e18c3a3 100644 --- a/controllers/search_controller.rb +++ b/controllers/search_controller.rb @@ -4,64 +4,101 @@ class SearchController < ApplicationController namespace "/search" do # execute a search query + get do - process_search() + page = process_search + reply 200, page end post do - process_search() + page = process_search + reply 200, page end - private - - def process_search(params=nil) - params ||= @params - text = params["q"] - - query = get_term_search_query(text, params) - # puts "Edismax query: #{query}, params: #{params}" - set_page_params(params) - - docs = Array.new - resp = LinkedData::Models::Class.search(query, params) - total_found = resp["response"]["numFound"] - add_matched_fields(resp, Sinatra::Helpers::SearchHelper::MATCH_TYPE_PREFLABEL) - ontology_rank = LinkedData::Models::Ontology.rank - - resp["response"]["docs"].each do |doc| - doc = doc.symbolize_keys - # NCBO-974 - doc[:matchType] = resp["match_types"][doc[:id]] - resource_id = doc[:resource_id] - doc.delete :resource_id - doc[:id] = resource_id - # TODO: The `rescue next` on the following line shouldn't be here - # However, at some point we didn't store the ontologyId in the index - # and these records haven't been cleared out so this is getting skipped - ontology_uri = doc[:ontologyId].sub(/\/submissions\/.*/, "") rescue next - ontology = LinkedData::Models::Ontology.read_only(id: ontology_uri, acronym: doc[:submissionAcronym]) - submission = LinkedData::Models::OntologySubmission.read_only(id: doc[:ontologyId], ontology: ontology) - doc[:submission] = submission - doc[:ontology_rank] = (ontology_rank[doc[:submissionAcronym]] && !ontology_rank[doc[:submissionAcronym]].empty?) ? ontology_rank[doc[:submissionAcronym]][:normalizedScore] : 0.0 - doc[:properties] = MultiJson.load(doc.delete(:propertyRaw)) if include_param_contains?(:properties) - instance = doc[:provisional] ? LinkedData::Models::ProvisionalClass.read_only(doc) : LinkedData::Models::Class.read_only(doc) - filter_language_attributes(params, instance) - docs.push(instance) - end + namespace "/ontologies" do + get do + query = params[:query] || params[:q] + options = get_ontology_metadata_search_options(params) + page_data = search(Ontology, query, options) + total_found = page_data.aggregate + ontology_rank = LinkedData::Models::Ontology.rank + docs = {} + acronyms_ids = {} + + page_data.each do |doc| + resource_id = doc["resource_id"] + id = doc["submissionId_i"] + acronym = doc["ontology_acronym_text"] + old_resource_id = acronyms_ids[acronym] + old_id = old_resource_id.split('/').last.to_i rescue 0 + + already_found = (old_id && id && (id <= old_id)) + not_restricted = (doc["ontology_viewingRestriction_t"]&.eql?('public') || current_user&.admin?) + user_not_restricted = not_restricted || + Array(doc["ontology_viewingRestriction_txt"]).any? {|u| u.split('/').last == current_user&.username} || + Array(doc["ontology_acl_txt"]).any? {|u| u.split('/').last == current_user&.username} + + user_restricted = !user_not_restricted - unless params['sort'] - if !text.nil? && text[-1] == '*' - docs.sort! {|a, b| [b[:score], a[:prefLabelExact].downcase, b[:ontology_rank]] <=> [a[:score], b[:prefLabelExact].downcase, a[:ontology_rank]]} - else - docs.sort! {|a, b| [b[:score], b[:ontology_rank]] <=> [a[:score], a[:ontology_rank]]} + if acronym.blank? || already_found || user_restricted + total_found -= 1 + next + end + + docs.delete(old_resource_id) + acronyms_ids[acronym] = resource_id + + doc["ontology_rank"] = ontology_rank.dig(doc["ontology_acronym_text"], :normalizedScore) || 0.0 + docs[resource_id] = doc end + + docs = docs.values + + docs.sort! { |a, b| [b["score"], b["ontology_rank"]] <=> [a["score"], a["ontology_rank"]] } unless params[:sort].present? + + page = page_object(docs, total_found) + + reply 200, page end - #need to return a Page object - page = page_object(docs, total_found) + get '/content' do + query = params[:query] || params[:q] + page, page_size = page_params - reply 200, page + ontologies = params.fetch("ontologies", "").split(',') + + unless current_user&.admin? + restricted_acronyms = restricted_ontologies_to_acronyms(params) + ontologies = ontologies.empty? ? restricted_acronyms : ontologies & restricted_acronyms + end + + types = params.fetch("types", "").split(',') + qf = params.fetch("qf", "") + + qf = [ + "ontology_t^100 resource_id^10", + "http___www.w3.org_2004_02_skos_core_prefLabel_txt^30", + "http___www.w3.org_2004_02_skos_core_prefLabel_t^30", + "http___www.w3.org_2000_01_rdf-schema_label_txt^30", + "http___www.w3.org_2000_01_rdf-schema_label_t^30", + ].join(' ') if qf.blank? + + fq = [] + + fq << ontologies.map { |x| "ontology_t:\"#{x}\"" }.join(' OR ') unless ontologies.blank? + fq << types.map { |x| "type_t:\"#{x}\" OR type_txt:\"#{x}\"" }.join(' OR ') unless types.blank? + + + conn = SOLR::SolrConnector.new(Goo.search_conf, :ontology_data) + resp = conn.search(query, fq: fq, qf: qf, defType: "edismax", + start: (page - 1) * page_size, rows: page_size) + + total_found = resp["response"]["numFound"] + docs = resp["response"]["docs"] + + reply 200, page_object(docs, total_found) + end end end -end +end \ No newline at end of file From 96c7e1df4b68c55b00c062e1d485f34b5b28fa80 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 14:44:09 -0800 Subject: [PATCH 044/173] added ability to filter and paginate submission endpoint --- .../ontology_submissions_controller.rb | 11 +- helpers/application_helper.rb | 55 ++-- helpers/submission_helper.rb | 38 ++- .../test_ontology_submissions_controller.rb | 245 +++++++++++++++++- 4 files changed, 297 insertions(+), 52 deletions(-) diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index 1b9463103..bdda6f65f 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -3,8 +3,15 @@ class OntologySubmissionsController < ApplicationController get "/submissions" do check_last_modified_collection(LinkedData::Models::OntologySubmission) - options = { also_include_views: params["also_include_views"], status: (params["include_status"] || "ANY") } - reply retrieve_latest_submissions(options).values + options = { + also_include_views: params["also_include_views"], + status: (params["include_status"] || "ANY") + } + subs = retrieve_latest_submissions(options) + subs = subs.values unless page? + # Force to show ontology reviews, notes and projects by default only for this request + LinkedData::Models::Ontology.serialize_default(*(LinkedData::Models::Ontology.hypermedia_settings[:serialize_default] + [:reviews, :notes, :projects])) + reply subs end ## diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index c2f3da7b2..3ed838d30 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -13,7 +13,7 @@ module ApplicationHelper ## # Escape text for use in html def h(text) - Rack::Utils.escape_html(text) + Rack::Utils.escape_html(text).gsub('/', '/') end ## @@ -225,7 +225,7 @@ def error(*message) # Look for the includes parameter and provide a formatted list of attributes def includes_param if @params["display"] - return @params["display"].split(",").map {|e| e.to_sym} + return @params["display"].split(",").map { |e| e.to_sym } end Array.new end @@ -233,14 +233,14 @@ def includes_param ## # Look for the ontologies acronym and give back a formatted list of ontolody id uris # This can be called without passing an argument and it will use the values from the current request - def ontologies_param(params=nil) + def ontologies_param(params = nil) params ||= @params if params["ontologies"] # Get list - ontologies = params["ontologies"].split(",").map {|o| o.strip} + ontologies = params["ontologies"].split(",").map { |o| o.strip } # When they aren't URIs, make them URIs - ontologies.map! {|o| o.start_with?("http://") ? replace_url_prefix(o) : ontology_uri_from_acronym(o)} + ontologies.map! { |o| o.start_with?("http://") ? replace_url_prefix(o) : ontology_uri_from_acronym(o) } if ontologies.include? nil error 404, "The ontologies parameter `[#{params["ontologies"]}]` includes non-existent acronyms. Notice that acronyms are case sensitive." end @@ -249,7 +249,7 @@ def ontologies_param(params=nil) Array.new end - def restricted_ontologies(params=nil) + def restricted_ontologies(params = nil) params ||= @params found_onts = false @@ -278,23 +278,23 @@ def restricted_ontologies(params=nil) return onts end - def restricted_ontologies_to_acronyms(params=nil, onts=nil) + def restricted_ontologies_to_acronyms(params = nil, onts = nil) onts ||= restricted_ontologies(params) - return onts.map {|o| o.acronym } + return onts.map { |o| o.acronym } end - def ontologies_param_to_acronyms(params=nil) + def ontologies_param_to_acronyms(params = nil) ontResourceIds = ontologies_param(params) - return ontResourceIds.map { |ontResourceId| ontResourceId.to_s.split('/')[-1]} + return ontResourceIds.map { |ontResourceId| ontResourceId.to_s.split('/')[-1] } end ## # Get semantic types parameter in the form [semantic_types=T099,T085,T345] - def semantic_types_param(params=nil) + def semantic_types_param(params = nil) params ||= @params if params["semantic_types"] - semanticTypes = params["semantic_types"].split(",").map {|o| o.strip} + semanticTypes = params["semantic_types"].split(",").map { |o| o.strip } return semanticTypes end Array.new @@ -302,10 +302,10 @@ def semantic_types_param(params=nil) ## # Get cui parameter in the form [cui=C0302369,C0522224,C0176617] - def cui_param(params=nil) + def cui_param(params = nil) params ||= @params if params["cui"] - cui = params["cui"].split(",").map {|o| o.strip} + cui = params["cui"].split(",").map { |o| o.strip } return cui end Array.new @@ -316,7 +316,7 @@ def month_param(params=nil) params ||= @params if params["month"] month = params["month"].strip - if %r{(?^(0[1-9]|[1-9]|1[0-2])$)}x === month + if /(?^(0[1-9]|[1-9]|1[0-2])$)/x === month return month.to_i.to_s end end @@ -324,11 +324,11 @@ def month_param(params=nil) end # validates year for starting with 1 or 2 and containing 4 digits - def year_param(params=nil) + def year_param(params = nil) params ||= @params if params["year"] year = params["year"].strip - if %r{(?^([1-2]\d{3})$)}x === year + if /(?^([1-2]\d{3})$)/x === year return year.to_i.to_s end end @@ -368,14 +368,14 @@ def ontology_from_acronym(acronym) def ontology_objects_from_params(params = nil) ontologies = Set.new(ontologies_param(params)) all_onts = LinkedData::Models::Ontology.where.include(LinkedData::Models::Ontology.goo_attrs_to_load).to_a - all_onts.select {|o| ontologies.include?(o.id.to_s)} + all_onts.select { |o| ontologies.include?(o.id.to_s) } end def ontology_uri_acronym_map cached_map = naive_expiring_cache_read(__method__) return cached_map if cached_map map = {} - LinkedData::Models::Ontology.where.include(:acronym).all.each {|o| map[o.acronym] = o.id.to_s} + LinkedData::Models::Ontology.where.include(:acronym).all.each { |o| map[o.acronym] = o.id.to_s } naive_expiring_cache_write(__method__, map) map end @@ -384,7 +384,7 @@ def acronym_ontology_uri_map cached_map = naive_expiring_cache_read(__method__) return cached_map if cached_map map = {} - LinkedData::Models::Ontology.where.include(:acronym).all.each {|o| map[o.id.to_s] = o.acronym} + LinkedData::Models::Ontology.where.include(:acronym).all.each { |o| map[o.id.to_s] = o.acronym } naive_expiring_cache_write(__method__, map) map end @@ -424,6 +424,21 @@ def replace_url_prefix(id) LinkedData::Models::Base.replace_url_prefix_to_id(id) end + def retrieve_latest_submissions(options = {}) + submissions = retrieve_submissions(options) + + latest_submissions = page? ? submissions : {} # latest_submission doest not work with pagination + submissions.each do |sub| + unless page? + next if include_ready?(options) && !sub.ready? + next if sub.ontology.nil? + latest_submissions[sub.ontology.acronym] ||= sub + latest_submissions[sub.ontology.acronym] = sub if sub.submissionId.to_i > latest_submissions[sub.ontology.acronym].submissionId.to_i + end + end + latest_submissions + end + def get_ontology_and_submission ont = Ontology.find(@params["ontology"]) .include(:acronym, :administeredBy, :acl, :viewingRestriction) diff --git a/helpers/submission_helper.rb b/helpers/submission_helper.rb index 0e095bb18..d5a6a400a 100644 --- a/helpers/submission_helper.rb +++ b/helpers/submission_helper.rb @@ -6,24 +6,33 @@ module SubmissionHelper def submission_include_params # When asking to display all metadata, we are using bring_remaining on each submission. Slower but best way to retrieve all attrs includes = OntologySubmission.goo_attrs_to_load(includes_param) - if includes.find { |v| v.is_a?(Hash) && v.keys.include?(:ontology) } - includes << { :ontology => [:administeredBy, :acronym, :name, :viewingRestriction, :group, :hasDomain, :notes, :reviews, :projects, :acl, :viewOf] } + if includes.find{|v| v.is_a?(Hash) && v.keys.include?(:ontology)} + includes << {:ontology=>[:administeredBy, :acronym, :name, :viewingRestriction, :group, :hasDomain,:notes, :reviews, :projects,:acl, :viewOf]} end - if includes.find { |v| v.is_a?(Hash) && v.keys.include?(:contact) } - includes << { :contact => [:name, :email] } + if includes.find{|v| v.is_a?(Hash) && v.keys.include?(:contact)} + includes << {:contact=>[:name, :email]} end - if includes.find { |v| v.is_a?(Hash) && v.keys.include?(:metrics) } + if includes.find{|v| v.is_a?(Hash) && v.keys.include?(:metrics)} includes << { metrics: [:maxChildCount, :properties, :classesWithMoreThan25Children, :classesWithOneChild, :individuals, :maxDepth, :classes, :classesWithNoDefinition, :averageChildCount, :numberOfAxioms, - :entities] } + :entities]} end includes end + def submission_attributes_all + out = [LinkedData::Models::OntologySubmission.embed_values_hash] + out << {:contact=>[:name, :email]} + out << {:ontology=>[:acronym, :name, :administeredBy, :group, :viewingRestriction, :doNotUpdate, :flat, + :hasDomain, :summaryOnly, :acl, :viewOf, :ontologyType]} + + out + end + def retrieve_submissions(options) status = (options[:status] || "RDF").to_s.upcase status = "RDF" if status.eql?("READY") @@ -44,7 +53,9 @@ def retrieve_submissions(options) submissions_query = submissions_query.order_by(order_by) unless order_by.nil? + submissions_query = apply_submission_filters(submissions_query) submissions_query = submissions_query.filter(Goo::Filter.new(ontology: [:viewOf]).unbound) unless include_views + submissions_query = submissions_query.filter(filter) if filter? submissions = submissions_query.include(submission_include_params) if page? @@ -54,21 +65,6 @@ def retrieve_submissions(options) end end - def retrieve_latest_submissions(options = {}) - submissions = retrieve_submissions(options) - - latest_submissions = page? ? submissions : {} # latest_submission doest not work with pagination - submissions.each do |sub| - unless page? - next if include_ready?(options) && !sub.ready? - next if sub.ontology.nil? - latest_submissions[sub.ontology.acronym] ||= sub - latest_submissions[sub.ontology.acronym] = sub if sub.submissionId.to_i > latest_submissions[sub.ontology.acronym].submissionId.to_i - end - end - latest_submissions - end - def include_ready?(options) options[:status] && options[:status].to_s.upcase.eql?("READY") end diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 3a5712f15..30c74bba2 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -29,7 +29,7 @@ def setup end def test_submissions_for_given_ontology - num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) + _, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) ontology = created_ont_acronyms.first get "/ontologies/#{ontology}/submissions" assert last_response.ok? @@ -68,7 +68,7 @@ def test_create_new_ontology_submission end def test_patch_ontology_submission - num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) + _, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1) ont = Ontology.find(created_ont_acronyms.first).include(submissions: [:submissionId, {ontology: :acronym}]).first assert_operator ont.submissions.length, :>, 0 submission = ont.submissions[0] @@ -112,7 +112,7 @@ def test_patch_submission_ignores_system_controlled_attributes end def test_delete_ontology_submission - num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1, + _, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1, random_submission_count: false, submission_count: 5) acronym = created_ont_acronyms.first submission_to_delete = (1..5).to_a.sample @@ -218,13 +218,13 @@ def test_download_submission # see also test_ontologies_controller::test_download_ontology # Test downloads of nonexistent ontology - get "/ontologies/BOGUS66/submissions/55/download" + get '/ontologies/BOGUS66/submissions/55/download' assert_equal(422, last_response.status, "failed to handle downloads of nonexistent ontology" + get_errors(last_response)) end def test_download_ontology_submission_rdf - count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, + _, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: true) acronym = created_ont_acronyms.first ont = onts.first @@ -239,7 +239,7 @@ def test_download_ontology_submission_rdf end def test_download_acl_only - count, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, + _, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 1, process_submission: false) acronym = created_ont_acronyms.first ont = onts.first.bring_remaining @@ -288,7 +288,7 @@ def test_download_acl_only def test_submissions_default_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + _, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) submission_default_attributes = LinkedData::Models::OntologySubmission.hypermedia_settings[:serialize_default].map(&:to_s) @@ -314,7 +314,7 @@ def test_submissions_default_includes def test_submissions_all_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + _, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) def submission_all_attributes attrs = OntologySubmission.goo_attrs_to_load([:all]) @@ -361,7 +361,7 @@ def submission_all_attributes def test_submissions_custom_includes ontology_count = 5 - num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, + _, created_ont_acronyms, _ = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) include = "ontology,contact,submissionId" @@ -398,6 +398,233 @@ def test_submissions_custom_includes assert_submission_contact_structure(sub) end + def test_ontology_submissions_access_controller + _, created_ont_acronyms, onts = create_ontologies_and_submissions(ont_count: 2, submission_count: 1, process_submission: false) + # case first submission is private + created_ont_acronyms.first + ont = onts.first.bring_remaining + + begin + allowed_user = User.new({ + username: 'allowed', + email: 'test@example.org', + password: '12345' + }) + allowed_user.save + blocked_user = User.new({ + username: 'blocked', + email: 'test1254@example.org', + password: '12345' + }) + blocked_user.save + + ont.acl = [allowed_user] + ont.viewingRestriction = 'private' + ont.save + + LinkedData.settings.enable_security = true + + get "/submissions?apikey=#{allowed_user.apikey}" + assert_equal 200, last_response.status + submissions = MultiJson.load(last_response.body) + assert_equal 2, submissions.size + + get "/submissions?apikey=#{blocked_user.apikey}" + assert_equal 200, last_response.status + submissions = MultiJson.load(last_response.body) + assert_equal 1, submissions.size + ensure + LinkedData.settings.enable_security = false + del = User.find('allowed').first + del.delete if del + del = User.find('blocked').first + del.delete if del + end + end + + def test_submissions_pagination + create_ontologies_and_submissions(ont_count: 2, submission_count: 2) + + get '/submissions' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + + assert_equal 2, submissions.length + + get '/submissions?page=1&pagesize=1' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal 1, submissions['collection'].length + end + + def test_submissions_pagination_filter + num_onts_created, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: 10, submission_count: 1) + group1 = LinkedData::Models::Group.new(acronym: 'group-1', name: 'Test Group 1').save + group2 = LinkedData::Models::Group.new(acronym: 'group-2', name: 'Test Group 2').save + category1 = LinkedData::Models::Category.new(acronym: 'category-1', name: 'Test Category 1').save + category2 = LinkedData::Models::Category.new(acronym: 'category-2', name: 'Test Category 2').save + + ontologies1 = ontologies[0..5].each do |o| + o.bring_remaining + o.group = [group1] + o.hasDomain = [category1] + o.save + end + + ontologies2 = ontologies[6..8].each do |o| + o.bring_remaining + o.group = [group2] + o.hasDomain = [category2] + o.save + end + + # test filter by group and category + get "/submissions?page=1&pagesize=100&group=#{group1.acronym}" + assert last_response.ok? + assert_equal ontologies1.size, MultiJson.load(last_response.body)['collection'].length + get "/submissions?page=1&pagesize=100&group=#{group2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)['collection'].length + get "/submissions?page=1&pagesize=100&hasDomain=#{category1.acronym}" + assert last_response.ok? + assert_equal ontologies1.size, MultiJson.load(last_response.body)['collection'].length + get "/submissions?page=1&pagesize=100&hasDomain=#{category2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)['collection'].length + get "/submissions?page=1&pagesize=100&hasDomain=#{category2.acronym}&group=#{group1.acronym}" + assert last_response.ok? + assert_equal 0, MultiJson.load(last_response.body)['collection'].length + get "/submissions?page=1&pagesize=100&hasDomain=#{category2.acronym}&group=#{group2.acronym}" + assert last_response.ok? + assert_equal ontologies2.size, MultiJson.load(last_response.body)['collection'].length + + ontologies3 = ontologies[9] + ontologies3.bring_remaining + ontologies3.group = [group1, group2] + ontologies3.hasDomain = [category1, category2] + ontologies3.name = 'name search test' + ontologies3.save + + # test search with acronym + [ + [ 1, ontologies.first.acronym], + [ 1, ontologies.last.acronym], + [ontologies.size, 'TEST-ONT'] + ].each do |count, acronym_search| + get "/submissions?page=1&pagesize=100&acronym=#{acronym_search}" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal count, submissions['collection'].length + end + + # test search with name + [ + [ 1, ontologies.first.name], + [ 1, ontologies.last.name], + [ontologies.size - 1, 'TEST-ONT'] + ].each do |count, name_search| + get "/submissions?page=1&pagesize=100&name=#{name_search}" + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + binding.pry unless submissions['collection'].length.eql?(count) + assert_equal count, submissions['collection'].length + end + + # test search with name and acronym + # search by name + get '/submissions?page=1&pagesize=100&name=search&acronym=search' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal 1, submissions['collection'].length + # search by acronym + get '/submissions?page=1&pagesize=100&name=9&acronym=9' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal 1, submissions['collection'].length + # search by acronym or name + get '/submissions?page=1&pagesize=100&name=search&acronym=8' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal 2, submissions['collection'].length + + ontologies.first.name = 'sort by test' + ontologies.first.save + sub = ontologies.first.latest_submission(status: :any).bring_remaining + sub.status = 'retired' + sub.description = '234' + sub.creationDate = DateTime.yesterday.to_datetime + sub.hasOntologyLanguage = LinkedData::Models::OntologyFormat.find('SKOS').first + sub.save + + #test search with sort + get '/submissions?page=1&pagesize=100&acronym=tes&name=tes&order_by=ontology_name' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal ontologies.map{|x| x.name}.sort, submissions['collection'].map{|x| x['ontology']['name']} + + get '/submissions?page=1&pagesize=100&acronym=tes&name=tes&order_by=creationDate' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal ontologies.map{|x| x.latest_submission(status: :any).bring(:creationDate).creationDate}.sort, submissions['collection'].map{|x| DateTime.parse(x['creationDate'])}.reverse + + # test search with format + get '/submissions?page=1&pagesize=100&acronym=tes&name=tes&hasOntologyLanguage=SKOS' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal 1, submissions['collection'].size + + get '/submissions?page=1&pagesize=100&acronym=tes&name=tes&hasOntologyLanguage=OWL' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal ontologies.size-1 , submissions['collection'].size + + # test ontology filter with submission filter attributes + get '/submissions?page=1&pagesize=100&acronym=tes&name=tes&group=group-2&category=category-2&hasOntologyLanguage=OWL' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal ontologies2.size + 1 , submissions['collection'].size + + # test ontology filter with status + get '/submissions?page=1&pagesize=100&status=retired' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal 1 , submissions['collection'].size + + get '/submissions?page=1&pagesize=100&status=alpha,beta,production' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + refute_empty submissions['collection'] + assert_equal ontologies.size - 1 , submissions['collection'].size + get '/submissions?page=1&pagesize=100&description=234&acronym=234&name=234' + assert last_response.ok? + submissions = MultiJson.load(last_response.body) + assert_equal 1 , submissions['collection'].size + end + + def test_submissions_param_include + skip('only for local development regrouping a set of tests') + test_submissions_default_includes + test_submissions_all_includes + test_submissions_custom_includes + end + + def test_submission_diff + _, _, onts = create_ontologies_and_submissions(ont_count: 1, submission_count: 2, + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, diff: true} ) + + ont = onts.first + sub = ont.latest_submission(status: :any) + + get "/ontologies/#{ont.acronym}/submissions/#{sub.submissionId}/diff" + end + private def submission_keys(sub) From 355e868f20b732b597fd54b9353d45c0a9c70ba0 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 15:04:25 -0800 Subject: [PATCH 045/173] refactored test_submissions_includes tests --- lib/rack/cube_reporter.rb | 41 ------- .../test_ontology_submissions_controller.rb | 104 ++++++------------ 2 files changed, 36 insertions(+), 109 deletions(-) delete mode 100644 lib/rack/cube_reporter.rb diff --git a/lib/rack/cube_reporter.rb b/lib/rack/cube_reporter.rb deleted file mode 100644 index d6694b874..000000000 --- a/lib/rack/cube_reporter.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'cube' - -## -# This enables collection of request statistics for anaylsis via cube. -# A cube server is required. See http://square.github.io/cube/ for more info. -module Rack - class CubeReporter - - def initialize(app = nil, options = {}) - host = options[:cube_host] || "localhost" - port = options[:cube_port] || 1180 - @app = app - @cube = ::Cube::Client.new(host, port) - end - - def call(env) - start = Time.now - data = @app.call(env) - finish = Time.now - cache_hit = !data[1]["X-Rack-Cache"].nil? && data[1]["X-Rack-Cache"].eql?("fresh") - user = env["REMOTE_USER"] - apikey = user.apikey if user - username = user.username if user - req_data = { - duration_ms: ((finish - start)*1000).ceil, - path: env["REQUEST_PATH"], - cache_hit: cache_hit, - status: data[0], - user: { - apikey: apikey, - username: username, - ip: env["REMOTE_ADDR"], - user_agent: env["HTTP_USER_AGENT"] - } - } - @cube.send "ontologies_api_request", DateTime.now, req_data - data - end - - end -end \ No newline at end of file diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 30c74bba2..5b185a089 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -314,88 +314,56 @@ def test_submissions_default_includes def test_submissions_all_includes ontology_count = 5 - _, created_ont_acronyms, ontologies = create_ontologies_and_submissions(ont_count: ontology_count, - submission_count: 1, submissions_to_process: []) - def submission_all_attributes - attrs = OntologySubmission.goo_attrs_to_load([:all]) - embed_attrs = attrs.find { |x| x.is_a?(Hash) } + _, created_ont_acronyms, = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) - attrs.delete_if { |x| x.is_a?(Hash) }.map(&:to_s) + embed_attrs.keys.map(&:to_s) - end - get("/submissions?include=all&display_links=false&display_context=false") + submission_all_attributes = begin + attrs = OntologySubmission.goo_attrs_to_load([:all]) + embed_attrs = attrs.select { |x| x.is_a?(Hash) }.first || {} + attrs.reject { |x| x.is_a?(Hash) }.map(&:to_s) + embed_attrs.keys.map(&:to_s) + end.sort - assert(last_response.ok?) - submissions = MultiJson.load(last_response.body) - assert_equal(ontology_count, submissions.size) + params = '?include=all&display_links=false&display_context=false' - submissions.each do |sub| - assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) - assert_submission_contact_structure(sub) - end + [ + "/submissions#{params}", + "/ontologies/#{created_ont_acronyms.first}/submissions#{params}", + "/ontologies/#{created_ont_acronyms.first}/latest_submission#{params}", + "/ontologies/#{created_ont_acronyms.first}/submissions/1#{params}" + ].each do |url| + get(url) + assert last_response.ok? - get("/ontologies/#{created_ont_acronyms.first}/submissions?include=all&display_links=false&display_context=false") + response_body = MultiJson.load(last_response.body) + submissions = response_body.is_a?(Array) ? response_body : [response_body] - assert(last_response.ok?) - submissions = MultiJson.load(last_response.body) - assert_equal(1, submissions.size) - - submissions.each do |sub| - assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) - assert_submission_contact_structure(sub) + assert_equal(ontology_count, submissions.size) if url == "/submissions#{params}" + assert(submissions.all? { |sub| submission_all_attributes.eql?(submission_keys(sub).sort) }) + assert(submissions.all? { |sub| sub['contact']&.first&.keys.to_a.sort.eql?(%w[name email id].sort) }) end - - get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=all&display_links=false&display_context=false") - assert(last_response.ok?) - sub = MultiJson.load(last_response.body) - - assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) - assert_submission_contact_structure(sub) - - get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=all&display_links=false&display_context=false") - assert(last_response.ok?) - sub = MultiJson.load(last_response.body) - - assert_equal(submission_all_attributes.sort, submission_keys(sub).sort) - assert_submission_contact_structure(sub) end def test_submissions_custom_includes ontology_count = 5 - _, created_ont_acronyms, _ = create_ontologies_and_submissions(ont_count: ontology_count, - submission_count: 1, submissions_to_process: []) - include = "ontology,contact,submissionId" - - get("/submissions?include=#{include}&display_links=false&display_context=false") + _, created_ont_acronyms, _ = create_ontologies_and_submissions(ont_count: ontology_count, submission_count: 1, submissions_to_process: []) + include_keys = %w[ontology contact submissionId] + params = "?include=#{include_keys.join(',')}&display_links=false&display_context=false" - assert(last_response.ok?) - submissions = MultiJson.load(last_response.body) - assert_equal ontology_count, submissions.size - submissions.each do |sub| - assert_equal(include.split(","), submission_keys(sub)) - assert_submission_contact_structure(sub) - end + [ + "/submissions#{params}", + "/ontologies/#{created_ont_acronyms.first}/submissions#{params}", + "/ontologies/#{created_ont_acronyms.first}/latest_submission#{params}", + "/ontologies/#{created_ont_acronyms.first}/submissions/1#{params}" + ].each do |url| + get(url) + assert last_response.ok? - get("/ontologies/#{created_ont_acronyms.first}/submissions?include=#{include}&display_links=false&display_context=false") + response_body = MultiJson.load(last_response.body) + submissions = response_body.is_a?(Array) ? response_body : [response_body] - assert(last_response.ok?) - submissions = MultiJson.load(last_response.body) - assert_equal(1, submissions.size) - submissions.each do |sub| - assert_equal(include.split(","), submission_keys(sub)) - assert_submission_contact_structure(sub) + assert_equal(ontology_count, submissions.size) if url == "/submissions#{params}" + assert(submissions.all? { |sub| include_keys.eql?(submission_keys(sub)) }) + assert(submissions.all? { |sub| sub['contact']&.first&.keys&.sort.eql?(%w[name email id].sort) }) end - - get("/ontologies/#{created_ont_acronyms.first}/latest_submission?include=#{include}&display_links=false&display_context=false") - assert(last_response.ok?) - sub = MultiJson.load(last_response.body) - assert_equal(include.split(","), submission_keys(sub)) - assert_submission_contact_structure(sub) - - get("/ontologies/#{created_ont_acronyms.first}/submissions/1?include=#{include}&display_links=false&display_context=false") - assert(last_response.ok?) - sub = MultiJson.load(last_response.body) - assert_equal(include.split(","), submission_keys(sub)) - assert_submission_contact_structure(sub) end def test_ontology_submissions_access_controller From 7eaf9cd127f2f8ca81c7f2a91e432d1d3fc05c4d Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 19:20:54 -0800 Subject: [PATCH 046/173] added test_mappings_slices test to test_slices_helper --- test/helpers/test_slices_helper.rb | 35 +++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/test/helpers/test_slices_helper.rb b/test/helpers/test_slices_helper.rb index bfe4b618b..33ed36abd 100644 --- a/test/helpers/test_slices_helper.rb +++ b/test/helpers/test_slices_helper.rb @@ -18,11 +18,11 @@ def before_suite end @@search_onts = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - ont_count: 2, - submission_count: 1, - acronym: "PARSED", - process_submission: true - })[2] + ont_count: 2, + submission_count: 1, + acronym: "PARSED", + process_submission: true + })[2] @@search_onts.first.bring_remaining @@search_onts.first.group = [@@group] @@search_onts.first.save @@ -33,7 +33,6 @@ def before_suite end def after_suite - LinkedData.settings.enable_slices = @@orig_slices_setting self.backend_4s_delete end @@ -77,12 +76,28 @@ def test_search_slices assert results.all? {|r| group_ids.include?(r["links"]["ontology"])} end + def test_mappings_slices + LinkedData::Mappings.create_mapping_counts(Logger.new(TestLogFile.new)) + + get "/mappings/statistics/ontologies" + + expected_result_without_slice = ["PARSED-0", "PARSED-1"] + + assert_equal expected_result_without_slice, MultiJson.load(last_response.body).keys.sort + + get "http://#{@@group_acronym}/mappings/statistics/ontologies" + + expected_result_with_slice = ["PARSED-0"] + + assert_equal expected_result_with_slice, MultiJson.load(last_response.body).keys.sort + end + private def self._create_group LinkedData::Models::Group.new({ - acronym: @@group_acronym, - name: "Test Group" - }).save + acronym: @@group_acronym, + name: "Test Group" + }).save end -end +end \ No newline at end of file From 4a9ffbdf6a2e8cd67a2a53d16bbf63dfa727d6c7 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 19:22:45 -0800 Subject: [PATCH 047/173] ruby 3.2 compatibility updates --- Gemfile.lock | 2 +- app.rb | 2 ++ controllers/batch_controller.rb | 2 +- controllers/mappings_controller.rb | 16 ++++++---- controllers/ontology_analytics_controller.rb | 13 ++++----- lib/rack/param_translator.rb | 3 -- test/controllers/test_batch_controller.rb | 8 ++--- test/controllers/test_classes_controller.rb | 2 +- test/controllers/test_mappings_controller.rb | 10 +++---- .../controllers/test_ontologies_controller.rb | 2 +- test/helpers/test_application_helper.rb | 18 ++++++------ test/test_case.rb | 29 +++++++++++-------- 12 files changed, 57 insertions(+), 50 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index bac68a276..39d782251 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 5c84a23b51efe4a757683071dcd0559c674252bc + revision: 7373727da30d09f7556c550798ed14bed0e99383 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/app.rb b/app.rb index 53854e10f..c3be5ba66 100644 --- a/app.rb +++ b/app.rb @@ -48,6 +48,8 @@ use Rack::Static, :urls => ["/static"], :root => "public" +set :public_folder, File.expand_path('public', __dir__) +set :static, true # Setup the environment environment = settings.environment.nil? ? :development : settings.environment diff --git a/controllers/batch_controller.rb b/controllers/batch_controller.rb index 2ee9b88ca..33276cc8d 100644 --- a/controllers/batch_controller.rb +++ b/controllers/batch_controller.rb @@ -15,7 +15,7 @@ class BatchController < ApplicationController goo_include = LinkedData::Models::Class.goo_attrs_to_load(incl) class_id_by_ontology = {} collection.each do |class_input| - unless class_input.instance_of?(Hash) + unless class_input.is_a?(Hash) error 422, "The collection param needs to be { 'class' : CLS_ID, 'ontology' : ont_id }" end unless class_input.include?("ontology") and class_input.include?("class") diff --git a/controllers/mappings_controller.rb b/controllers/mappings_controller.rb index 29e26483a..64ffc799d 100644 --- a/controllers/mappings_controller.rb +++ b/controllers/mappings_controller.rb @@ -166,11 +166,13 @@ class MappingsController < ApplicationController persistent_counts = {} f = Goo::Filter.new(:pair_count) == false LinkedData::Models::MappingCount.where.filter(f) - .include(:ontologies,:count) - .all - .each do |m| + .include(:ontologies, :count) + .all + .each do |m| persistent_counts[m.ontologies.first] = m.count end + ont_acronyms = restricted_ontologies_to_acronyms(params) + persistent_counts = persistent_counts.select { |key, _| ont_acronyms.include?(key) || key.start_with?("http://") } reply persistent_counts end @@ -189,9 +191,9 @@ class MappingsController < ApplicationController persistent_counts = {} LinkedData::Models::MappingCount.where(pair_count: true) .and(ontologies: ontology.acronym) - .include(:ontologies,:count) - .all - .each do |m| + .include(:ontologies, :count) + .all + .each do |m| other = m.ontologies.first if other == ontology.acronym other = m.ontologies[1] @@ -200,5 +202,7 @@ class MappingsController < ApplicationController end reply persistent_counts end + end end + diff --git a/controllers/ontology_analytics_controller.rb b/controllers/ontology_analytics_controller.rb index 829708c13..b4435e8f7 100644 --- a/controllers/ontology_analytics_controller.rb +++ b/controllers/ontology_analytics_controller.rb @@ -4,14 +4,14 @@ class OntologyAnalyticsController < ApplicationController ## # get all ontology analytics for a given year/month combination - namespace "/analytics" do + namespace '/analytics' do get do expires 86400, :public year = year_param(params) - error 400, "The year you supplied is invalid. Valid years start with 2 and contain 4 digits." if params["year"] && !year + error 400, 'The year you supplied is invalid. Valid years start with 2 and contain 4 digits.' if params['year'] && !year month = month_param(params) - error 400, "The month you supplied is invalid. Valid months are 1-12." if params["month"] && !month + error 400, 'The month you supplied is invalid. Valid months are 1-12.' if params['month'] && !month acronyms = restricted_ontologies_to_acronyms(params) analytics = Ontology.analytics(year, month, acronyms) @@ -22,7 +22,7 @@ class OntologyAnalyticsController < ApplicationController ## # get all analytics for a given ontology - namespace "/ontologies/:acronym/analytics" do + namespace '/ontologies/:acronym/analytics' do get do expires 86400, :public @@ -34,7 +34,7 @@ class OntologyAnalyticsController < ApplicationController error 400, "The month you supplied is invalid. Valid months are 1-12." if params["month"] && !month analytics = ont.analytics(year, month) - if params["format"].to_s.downcase.eql?("csv") + if params['format'].to_s.downcase.eql?("csv") tf = Tempfile.new("analytics-#{params['acronym']}") csv = CSV.new(tf, headers: true, return_headers: true, write_headers: true) csv << [:month, :visits] @@ -50,8 +50,7 @@ class OntologyAnalyticsController < ApplicationController end end csv.close - content_type "text/csv" - send_file tf.path, filename: "analytics-#{params['acronym']}.csv" + send_file tf.path, filename: "analytics-#{params['acronym']}.csv", type: 'text/csv', status: 200 else reply analytics end diff --git a/lib/rack/param_translator.rb b/lib/rack/param_translator.rb index 20738b2a5..93798f591 100644 --- a/lib/rack/param_translator.rb +++ b/lib/rack/param_translator.rb @@ -1,6 +1,3 @@ -## -# This enables collection of request statistics for anaylsis via cube. -# A cube server is required. See http://square.github.io/cube/ for more info. module Rack class ParamTranslator diff --git a/test/controllers/test_batch_controller.rb b/test/controllers/test_batch_controller.rb index 492a608ff..faea8be5b 100644 --- a/test/controllers/test_batch_controller.rb +++ b/test/controllers/test_batch_controller.rb @@ -22,7 +22,7 @@ def test_class_batch_one_ontology "display" => "prefLabel,synonym" } } - post "/batch/", call_params + post "/batch", call_params assert last_response.ok? data = MultiJson.load(last_response.body) classes = data["http://www.w3.org/2002/07/owl#Class"] @@ -48,7 +48,7 @@ def test_class_wrong_params "display" => "prefLabel,synonym" } } - post "/batch/", call_params + post "/batch", call_params assert_equal 422, last_response.status end @@ -72,7 +72,7 @@ def test_class_batch_multiple "display" => "prefLabel" } } - post "/batch/", call_params + post "/batch", call_params assert last_response.ok? data = MultiJson.load(last_response.body) classes = data["http://www.w3.org/2002/07/owl#Class"] @@ -101,7 +101,7 @@ def test_class_all_bro "display" => "prefLabel" } } - post "/batch/", call_params + post "/batch", call_params assert last_response.ok? # refute last_response.ok? data = MultiJson.load(last_response.body) diff --git a/test/controllers/test_classes_controller.rb b/test/controllers/test_classes_controller.rb index 838385d7e..ca8d64f2d 100644 --- a/test/controllers/test_classes_controller.rb +++ b/test/controllers/test_classes_controller.rb @@ -422,7 +422,7 @@ def test_calls_not_found escaped_cls= CGI.escape("http://my.bogus.inexistent.class/that/this/is") #404 on ontology - get "/ontologies/NO-ONT-ZZZZZZ/classes/" + get "/ontologies/NO-ONT-ZZZZZZ/classes" assert last_response.status == 404 get "/ontologies/NO-ONT-ZZZZZZ/classes/#{escaped_cls}/children" assert last_response.status == 404 diff --git a/test/controllers/test_mappings_controller.rb b/test/controllers/test_mappings_controller.rb index d8c6f6192..8d687fd70 100644 --- a/test/controllers/test_mappings_controller.rb +++ b/test/controllers/test_mappings_controller.rb @@ -103,7 +103,7 @@ def mappings_between_ontologies ] ontologies_params.each do |ontologies| ont1, ont2 = ontologies.split(",") - get "/mappings/?ontologies=#{ontologies}" + get "/mappings?ontologies=#{ontologies}" assert last_response.ok? mappings = MultiJson.load(last_response.body) #pages @@ -219,7 +219,7 @@ def create_mapping creator: "http://data.bioontology.org/users/tim" } - post "/mappings/", + post "/mappings", MultiJson.dump(mapping), "CONTENT_TYPE" => "application/json" @@ -259,7 +259,7 @@ def create_mapping end assert rest_count == 3 - get "/mappings/recent/" + get "/mappings/recent" assert last_response.status == 200 response = MultiJson.load(last_response.body) assert (response.length == 5) @@ -314,7 +314,7 @@ def delete_mapping creator: "http://data.bioontology.org/users/tim" } - post "/mappings/", + post "/mappings", MultiJson.dump(mapping), "CONTENT_TYPE" => "application/json" @@ -363,7 +363,7 @@ def mappings_statistics end NcboCron::Models::QueryWarmer.new(Logger.new(TestLogFile.new)).run assert LinkedData::Models::MappingCount.where.all.length > 2 - get "/mappings/statistics/ontologies/" + get "/mappings/statistics/ontologies" assert last_response.ok? stats = MultiJson.load(last_response.body) data = {"BRO-TEST-MAP-0"=>18, diff --git a/test/controllers/test_ontologies_controller.rb b/test/controllers/test_ontologies_controller.rb index 874efe394..37f7adcb0 100644 --- a/test/controllers/test_ontologies_controller.rb +++ b/test/controllers/test_ontologies_controller.rb @@ -97,7 +97,7 @@ def test_create_ontology assert last_response.status == 201 delete "/ontologies/#{@@acronym}" - post "/ontologies/", @@file_params.merge(acronym: @@acronym) + post "/ontologies", @@file_params.merge(acronym: @@acronym) assert last_response.status == 201 end diff --git a/test/helpers/test_application_helper.rb b/test/helpers/test_application_helper.rb index 2315a677d..6a46a07e6 100644 --- a/test/helpers/test_application_helper.rb +++ b/test/helpers/test_application_helper.rb @@ -9,22 +9,22 @@ def before_suite def test_it_escapes_html escaped_html = helper.h("http://testlink.com") - assert escaped_html.eql?("<a>http://testlink.com</a>") + assert_equal "<a>http://testlink.com</a>", escaped_html end def test_ontologies_param - ids = @@ontologies.map {|o| o.id.to_s} - acronyms = @@ontologies.map {|o| o.id.to_s.split("/").last} - params = {"ontologies" => acronyms.join(",")} + ids = @@ontologies.map { |o| o.id.to_s } + acronyms = @@ontologies.map { |o| o.id.to_s.split("/").last } + params = { "ontologies" => acronyms.join(",") } ontologies = ontologies_param(params) assert ontologies == ids - params = {"ontologies" => ids.join(",")} + params = { "ontologies" => ids.join(",") } ontologies = ontologies_param(params) assert ontologies == ids id_acronym = ids + acronyms - params = {"ontologies" => id_acronym.join(",")} + params = { "ontologies" => id_acronym.join(",") } ontologies = ontologies_param(params) assert ontologies == (ids + ids) end @@ -48,16 +48,16 @@ def test_acronym_from_ontology_uri def test_bad_accept_header_handling # This accept header contains '*; q=.2', which isn't valid according to the spec, should be '*/*; q=.2' bad_accept_header = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" - get "/ontologies", {}, {"HTTP_ACCEPT" => bad_accept_header} + get "/ontologies", {}, { "HTTP_ACCEPT" => bad_accept_header } assert last_response.status == 400 assert last_response.body.include?("Accept header `#{bad_accept_header}` is invalid") end def test_http_method_override - post "/ontologies", {}, {"HTTP_X_HTTP_METHOD_OVERRIDE" => "GET"} + post "/ontologies", {}, { "HTTP_X_HTTP_METHOD_OVERRIDE" => "GET" } assert last_response.ok? acronyms = @@ontologies.map {|o| o.bring(:acronym).acronym}.sort - resp_acronyms = MultiJson.load(last_response.body).map {|o| o["acronym"]}.sort + resp_acronyms = MultiJson.load(last_response.body).map { |o| o["acronym"] }.sort assert_equal acronyms, resp_acronyms end end diff --git a/test/test_case.rb b/test/test_case.rb index 1589e3ce2..f793932bc 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -28,21 +28,24 @@ require 'multi_json' require 'oj' require 'json-schema' - +require 'minitest/reporters' +Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new(:color => true), Minitest::Reporters::MeanTimeReporter.new] MAX_TEST_REDIS_SIZE = 10_000 # Check to make sure you want to run if not pointed at localhost safe_hosts = Regexp.new(/localhost|-ut|ncbo-dev*|ncbo-unittest*/) + def safe_redis_hosts?(sh) return [LinkedData.settings.http_redis_host, - Annotator.settings.annotator_redis_host, - LinkedData.settings.goo_redis_host].select { |x| + Annotator.settings.annotator_redis_host, + LinkedData.settings.goo_redis_host].select { |x| x.match(sh) }.length == 3 end + unless LinkedData.settings.goo_host.match(safe_hosts) && - safe_redis_hosts?(safe_hosts) && - LinkedData.settings.search_server_url.match(safe_hosts) + safe_redis_hosts?(safe_hosts) && + LinkedData.settings.search_server_url.match(safe_hosts) print "\n\n================================== WARNING ==================================\n" print "** TESTS CAN BE DESTRUCTIVE -- YOU ARE POINTING TO A POTENTIAL PRODUCTION/STAGE SERVER **\n" print "Servers:\n" @@ -155,7 +158,7 @@ def app # @option options [TrueClass, FalseClass] :process_submission Parse the test ontology file def create_ontologies_and_submissions(options = {}) if options[:process_submission] && options[:process_options].nil? - options[:process_options] = { process_rdf: true, extract_metadata: false, generate_missing_labels: false } + options[:process_options] = { process_rdf: true, extract_metadata: false, generate_missing_labels: false } end LinkedData::SampleData::Ontology.create_ontologies_and_submissions(options) end @@ -180,13 +183,13 @@ def delete_goo_models(gooModelArray) # @param [String] jsonData a json string that will be parsed by MultiJson.load # @param [String] jsonSchemaString a json schema string that will be parsed by MultiJson.load # @param [boolean] list set it true for jsonObj array of items to validate against jsonSchemaString - def validate_json(jsonData, jsonSchemaString, list=false) + def validate_json(jsonData, jsonSchemaString, list = false) schemaVer = :draft3 jsonObj = MultiJson.load(jsonData) jsonSchema = MultiJson.load(jsonSchemaString) assert( - JSON::Validator.validate(jsonSchema, jsonObj, :list => list, :version => schemaVer), - JSON::Validator.fully_validate(jsonSchema, jsonObj, :list => list, :version => schemaVer, :validate_schema => true).to_s + JSON::Validator.validate(jsonSchema, jsonObj, list: list, version: schemaVer), + JSON::Validator.fully_validate(jsonSchema, jsonObj, list: list, version: schemaVer, validate_schema: true).to_s ) end @@ -219,17 +222,17 @@ def self.reset_security(old_security = @@old_security_setting) end # Ensure a user exists; return it. Safe to call from anywhere. - def create_user(username, email: nil, password: "password") + def self.create_user(username, email: nil, password: "password") user = User.new(username: username, email: email || "#{username}@example.org", password: password) user.save if user.valid? user end - def ensure_user(username, email: nil, password: "password") + def self.ensure_user(username, email: nil, password: "password") User.find(username).first || create_user(username, email: email, password: password) end - def delete_user(username) + def self.delete_user(username) User.find(username).first&.delete end @@ -254,6 +257,7 @@ def unused_port end private + def port_in_use?(port) server = TCPServer.new(port) server.close @@ -263,3 +267,4 @@ def port_in_use?(port) end end + From 567110454f24dede44690610b327c77c08e87a9d Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 19:25:19 -0800 Subject: [PATCH 048/173] re-added cube but will remove it again --- lib/rack/cube_reporter.rb | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lib/rack/cube_reporter.rb diff --git a/lib/rack/cube_reporter.rb b/lib/rack/cube_reporter.rb new file mode 100644 index 000000000..d6694b874 --- /dev/null +++ b/lib/rack/cube_reporter.rb @@ -0,0 +1,41 @@ +require 'cube' + +## +# This enables collection of request statistics for anaylsis via cube. +# A cube server is required. See http://square.github.io/cube/ for more info. +module Rack + class CubeReporter + + def initialize(app = nil, options = {}) + host = options[:cube_host] || "localhost" + port = options[:cube_port] || 1180 + @app = app + @cube = ::Cube::Client.new(host, port) + end + + def call(env) + start = Time.now + data = @app.call(env) + finish = Time.now + cache_hit = !data[1]["X-Rack-Cache"].nil? && data[1]["X-Rack-Cache"].eql?("fresh") + user = env["REMOTE_USER"] + apikey = user.apikey if user + username = user.username if user + req_data = { + duration_ms: ((finish - start)*1000).ceil, + path: env["REQUEST_PATH"], + cache_hit: cache_hit, + status: data[0], + user: { + apikey: apikey, + username: username, + ip: env["REMOTE_ADDR"], + user_agent: env["HTTP_USER_AGENT"] + } + } + @cube.send "ontologies_api_request", DateTime.now, req_data + data + end + + end +end \ No newline at end of file From 65d1c3f27151896ce9e1ee248ced4faa32a6e9ed Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 19:30:35 -0800 Subject: [PATCH 049/173] removed cube integration as it's not being used --- Gemfile | 1 - Gemfile.lock | 2 -- app.rb | 5 ----- config/config.rb | 3 --- lib/rack/cube_reporter.rb | 41 --------------------------------------- 5 files changed, 52 deletions(-) delete mode 100644 lib/rack/cube_reporter.rb diff --git a/Gemfile b/Gemfile index f26ce6807..83cf4ec65 100644 --- a/Gemfile +++ b/Gemfile @@ -41,7 +41,6 @@ gem 'redis' gem 'redis-store' # Monitoring -gem 'cube-ruby', require: 'cube' gem 'newrelic_rpm', group: [:default, :deployment] # HTTP server diff --git a/Gemfile.lock b/Gemfile.lock index 39d782251..f7c91d712 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -175,7 +175,6 @@ GEM connection_pool (3.0.2) crack (0.4.5) rexml - cube-ruby (0.0.3) dante (0.2.0) date (3.5.1) docile (1.4.1) @@ -539,7 +538,6 @@ DEPENDENCIES capistrano-locally capistrano-rbenv crack (= 0.4.5) - cube-ruby ed25519 (>= 1.2, < 2.0) ffi goo! diff --git a/app.rb b/app.rb index c3be5ba66..3f73742bd 100644 --- a/app.rb +++ b/app.rb @@ -132,11 +132,6 @@ # Monitoring middleware if LinkedData::OntologiesAPI.settings.enable_monitoring - cube_settings = { - cube_host: LinkedData::OntologiesAPI.settings.cube_host, - cube_port: LinkedData::OntologiesAPI.settings.cube_port - } - use Rack::CubeReporter, cube_settings use Rack::SlowRequests, log_path: LinkedData::OntologiesAPI.settings.slow_request_log end diff --git a/config/config.rb b/config/config.rb index a67829071..d50035d6d 100644 --- a/config/config.rb +++ b/config/config.rb @@ -13,8 +13,6 @@ def config(&block) # Set defaults @settings.enable_monitoring ||= false - @settings.cube_host ||= "localhost" - @settings.cube_port ||= 1180 @settings.slow_request_log ||= File.expand_path("../../logs/slow_requests.log", __FILE__) @settings.http_redis_host ||= "localhost" @settings.http_redis_port ||= 6379 @@ -30,7 +28,6 @@ def config(&block) if @settings.enable_monitoring puts "(API) >> Slow queries log enabled: #{@settings.slow_request_log}" - puts "(API) >> Using cube server #{@settings.cube_host}:#{@settings.cube_port}" end end diff --git a/lib/rack/cube_reporter.rb b/lib/rack/cube_reporter.rb deleted file mode 100644 index d6694b874..000000000 --- a/lib/rack/cube_reporter.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'cube' - -## -# This enables collection of request statistics for anaylsis via cube. -# A cube server is required. See http://square.github.io/cube/ for more info. -module Rack - class CubeReporter - - def initialize(app = nil, options = {}) - host = options[:cube_host] || "localhost" - port = options[:cube_port] || 1180 - @app = app - @cube = ::Cube::Client.new(host, port) - end - - def call(env) - start = Time.now - data = @app.call(env) - finish = Time.now - cache_hit = !data[1]["X-Rack-Cache"].nil? && data[1]["X-Rack-Cache"].eql?("fresh") - user = env["REMOTE_USER"] - apikey = user.apikey if user - username = user.username if user - req_data = { - duration_ms: ((finish - start)*1000).ceil, - path: env["REQUEST_PATH"], - cache_hit: cache_hit, - status: data[0], - user: { - apikey: apikey, - username: username, - ip: env["REMOTE_ADDR"], - user_agent: env["HTTP_USER_AGENT"] - } - } - @cube.send "ontologies_api_request", DateTime.now, req_data - data - end - - end -end \ No newline at end of file From cc92729ba4bffdebf4ded92e83952a842ce9c9b7 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 21:51:32 -0800 Subject: [PATCH 050/173] removed the newrelic integration for now; it needs to be re-integrated --- Capfile | 3 +-- Gemfile | 3 --- Gemfile.lock | 3 --- app.rb | 3 --- config/deploy.rb | 1 - 5 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Capfile b/Capfile index 3bf9ae11e..95799ba1b 100644 --- a/Capfile +++ b/Capfile @@ -16,12 +16,11 @@ install_plugin Capistrano::SCM::Git # https://github.com/capistrano/rails # # require 'capistrano/rvm' -require 'capistrano/rbenv' +# require 'capistrano/rbenv' # require 'capistrano/chruby' require 'capistrano/bundler' # require 'capistrano/rails/assets' # require 'capistrano/rails/migrations' require 'capistrano/locally' -require 'new_relic/recipes' # announce deployments in NewRelic # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } diff --git a/Gemfile b/Gemfile index 83cf4ec65..6530b6d7a 100644 --- a/Gemfile +++ b/Gemfile @@ -40,9 +40,6 @@ gem 'redis-rack-cache' gem 'redis' gem 'redis-store' -# Monitoring -gem 'newrelic_rpm', group: [:default, :deployment] - # HTTP server gem 'unicorn' gem 'unicorn-worker-killer' diff --git a/Gemfile.lock b/Gemfile.lock index f7c91d712..894cabcba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -352,8 +352,6 @@ GEM net-protocol net-ssh (7.3.0) netrc (0.11.0) - newrelic_rpm (10.0.0) - logger oj (3.16.13) bigdecimal (>= 3.0) ostruct (>= 0.2) @@ -556,7 +554,6 @@ DEPENDENCIES ncbo_cron! ncbo_ontology_recommender! net-ftp - newrelic_rpm oj ontologies_linked_data! pandoc-ruby diff --git a/app.rb b/app.rb index 3f73742bd..08ed31a42 100644 --- a/app.rb +++ b/app.rb @@ -172,9 +172,6 @@ require_relative 'config/unicorn_workerkiller' end -# Add New Relic last to allow Rack middleware instrumentation -require 'newrelic_rpm' - # Initialize the app require_relative 'init' diff --git a/config/deploy.rb b/config/deploy.rb index 9c0b599ce..a764cd9fb 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -108,7 +108,6 @@ after :updating, :get_config after :publishing, :restart - after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do From 697af256dc2a9d7f7082e408ac5ee40507b57ed4 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 22:46:16 -0800 Subject: [PATCH 051/173] fixed oboId and notation searches --- helpers/search_helper.rb | 9 +++++---- test/controllers/test_search_controller.rb | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index e0b7ed542..46e43db4f 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -97,7 +97,7 @@ def get_term_search_query(text, params={}) if params[EXACT_MATCH_PARAM] == "true" query = "\"#{solr_escape(text)}\"" - params["qf"] = "resource_id^20 #{add_lang_suffix('prefLabel', '^10')} #{add_lang_suffix('synonymExact')} #{QUERYLESS_FIELDS_STR}" + params["qf"] = "resource_id^20 notation^20 oboId^20 #{add_lang_suffix('prefLabelExact', '^10')} #{add_lang_suffix('synonymExact')} #{QUERYLESS_FIELDS_STR_NO_IDS}" params["hl.fl"] = "resource_id #{add_lang_suffix('prefLabelExact')} #{add_lang_suffix('synonymExact')} #{QUERYLESS_FIELDS_STR}" elsif params[SUGGEST_PARAM] == "true" || text[-1] == '*' text.gsub!(/\*+$/, '') @@ -131,17 +131,18 @@ def get_term_search_query(text, params={}) params["qf"] = [ "resource_id^100", + "notation^100", + "oboId^100", add_lang_suffix('prefLabelExact', '^90'), add_lang_suffix('prefLabel', '^70'), add_lang_suffix('synonymExact', '^50'), add_lang_suffix('synonym', '^10'), - QUERYLESS_FIELDS_STR + QUERYLESS_FIELDS_STR_NO_IDS ].join(' ') params["qf"] << " property" if params[INCLUDE_PROPERTIES_PARAM] == "true" - + params["bq"] = "idAcronymMatch:true^80" params["hl.fl"] = "resource_id #{add_lang_suffix('prefLabelExact')} #{ add_lang_suffix('prefLabel')} #{add_lang_suffix('synonymExact')} #{add_lang_suffix('synonym')} #{QUERYLESS_FIELDS_STR}" - params["hl.fl"] = "#{params["hl.fl"]} property" if params[INCLUDE_PROPERTIES_PARAM] == "true" end diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index c8234c078..057dc40d5 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -269,7 +269,7 @@ def test_search_obo_id # mdorf, 3/2/2024, when the : is followed by a LETTER, as in NCIT:C20480, # then Solr does not split the query on the tokens, # but when the : is followed by a number, as in OGMS:0000071, - # then Solr does split this on tokens and shows the other resuluts + # then Solr does split this on tokens and shows the other results get "/search?q=OGMS:0000071" assert last_response.ok? results = MultiJson.load(last_response.body) From 7ce918848905b5d21d474d489e38d3533d7a4532 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 28 Jan 2026 22:52:41 -0800 Subject: [PATCH 052/173] fixed the unit test test_language_attribute_filter --- test/controllers/test_search_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index 057dc40d5..8ae369501 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -440,11 +440,11 @@ def test_language_attribute_filter assert last_response.ok? assert_equal 1, results["collection"].size doc = results["collection"][0] - assert doc["prefLabel"].kind_of?(Array) + assert doc["prefLabel"].kind_of?(Hash) assert_equal 3, doc["prefLabel"].size - assert doc["synonym"].kind_of?(Array) + assert doc["synonym"].kind_of?(Hash) assert_equal 1, doc["synonym"].size - assert doc["definition"].kind_of?(Array) + assert doc["definition"].kind_of?(Hash) assert_equal 2, doc["definition"].size end From e6971cb6c52947cdb4a6420fb019a710590dd725 Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 29 Jan 2026 15:26:31 -0800 Subject: [PATCH 053/173] resoved an issue with setting filenames in create_ontology --- Gemfile | 2 +- Gemfile.lock | 4 ++-- helpers/application_helper.rb | 18 ++++++++++++++++++ helpers/ontology_helper.rb | 26 +++++++------------------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Gemfile b/Gemfile index 6530b6d7a..3f031ea57 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,7 @@ gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/rdf3-compat' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' diff --git a/Gemfile.lock b/Gemfile.lock index 894cabcba..0d095ad7d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,8 +18,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 55e8cbfac358b2c40deb0bd963bfe6dee91e8347 - branch: develop + revision: fa8f225e6c3d3df4bdc03029b1598201d079b387 + branch: chore/rdf3-compat specs: ncbo_annotator (0.0.1) goo diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index 3ed838d30..64fd7da93 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -478,6 +478,24 @@ def include_param_contains?(str) return class_params_include || params_include end + ## + # Checks to see if the request has a file attached + def request_has_file? + @params.any? { |p, v| v.instance_of?(Hash) && v.key?(:tempfile) && v[:tempfile].instance_of?(Tempfile) } + end + + ## + # Looks for a file that was included as a multipart in a request + def file_from_request + @params.each_value do |value| + if value.is_a?(Hash) && value.key?(:tempfile) && value[:tempfile].instance_of?(Tempfile) + return value[:filename], value[:tempfile] + end + end + + [nil, nil] + end + # Long-operation helper modeled after the original from AdminController#process_long_operation # Start: "processing" # Success (empty/nil): "done" diff --git a/helpers/ontology_helper.rb b/helpers/ontology_helper.rb index e5798ff7d..b34724f74 100644 --- a/helpers/ontology_helper.rb +++ b/helpers/ontology_helper.rb @@ -16,7 +16,12 @@ def create_submission(ont) ont_submission.submissionId = submission_id # Get file info - add_file_to_submission(ont, ont_submission) + filename, tmpfile = add_file_to_submission(ont, ont_submission) + # if no actual file was uploaded, we remove the file parameters + if filename.nil? && tmpfile.nil? + params.delete("uploadFilePath") + params.delete("diffFilePath") + end # Add new format if it doesn't exist if ont_submission.hasOntologyLanguage.nil? @@ -35,23 +40,6 @@ def create_submission(ont) ont_submission end - ## - # Checks to see if the request has a file attached - def request_has_file? - @params.any? {|p,v| v.instance_of?(Hash) && v.key?(:tempfile) && v[:tempfile].instance_of?(Tempfile)} - end - - ## - # Looks for a file that was included as a multipart in a request - def file_from_request - @params.each do |param, value| - if value.instance_of?(Hash) && value.has_key?(:tempfile) && value[:tempfile].instance_of?(Tempfile) - return value[:filename], value[:tempfile] - end - end - return nil, nil - end - ## # Add a file to the submission if a file exists in the params def add_file_to_submission(ont, submission) @@ -69,7 +57,7 @@ def add_file_to_submission(ont, submission) file_location = OntologySubmission.copy_file_repository(ont.acronym, submission.submissionId, tmpfile, filename) submission.uploadFilePath = file_location end - return filename, tmpfile + [filename, tmpfile] end end end From 1601744bafcc53b9c81fc373f0183bf43979288a Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 29 Jan 2026 22:30:25 -0800 Subject: [PATCH 054/173] removed double-quoting around the test_search_security query based on goo commit: 98bd870 --- test/controllers/test_search_models_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index a6e24bb25..1b8139686 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -115,7 +115,7 @@ def test_search_security begin self.class.enable_security - get "/search/ontologies?query=\"#{bro.acronym}\"&apikey=#{blocked_user.apikey}" + get "/search/ontologies?query=#{bro.acronym}&apikey=#{blocked_user.apikey}" response = MultiJson.load(last_response.body)["collection"] assert_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} @@ -124,7 +124,7 @@ def test_search_security res = MultiJson.load(last_response.body) assert_equal 0, res['totalCount'] - get "/search/ontologies?query=\"#{bro.acronym}\"&apikey=#{allowed_user1.apikey}" + get "/search/ontologies?query=#{bro.acronym}&apikey=#{allowed_user1.apikey}" response = MultiJson.load(last_response.body)["collection"] refute_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)} From a8fb6e0e30c6edd051f174a1900f46df0a175595 Mon Sep 17 00:00:00 2001 From: mdorf Date: Thu, 29 Jan 2026 23:09:32 -0800 Subject: [PATCH 055/173] disabled test_search_custom_onts in test_users_helper due to its inconsistency, per AgroPortal --- Gemfile.lock | 2 +- .../test_search_models_controller.rb | 1 - test/helpers/test_users_helper.rb | 29 ++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0d095ad7d..ef6b04631 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: e0109a9ea9b0e0119c3e5cd19146514c2282fab0 + revision: 256afce837da44d31e8da1e08a6c7c56bbd1820f branch: ontoportal-lirmm-development specs: goo (0.0.2) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index 1b8139686..16cbecc0b 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -98,7 +98,6 @@ def test_search_security }) allowed_user2.save - blocked_user = User.new({ username: "blocked", email: "test3@example.org", diff --git a/test/helpers/test_users_helper.rb b/test/helpers/test_users_helper.rb index 6ceb686f4..e3e4e5dcf 100644 --- a/test/helpers/test_users_helper.rb +++ b/test/helpers/test_users_helper.rb @@ -8,16 +8,16 @@ def before_suite @@non_custom_user = self.class._create_user("notcustom") @@onts = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - ont_count: 5, - submission_count: 0 - })[2] + ont_count: 5, + submission_count: 0 + })[2] @@search_onts = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - ont_count: 2, - submission_count: 1, - acronym: "PARSED", - process_submission: true - })[2] + ont_count: 2, + submission_count: 1, + acronym: "PARSED", + process_submission: true + })[2] @@user_ont_search = @@search_onts.first @@user_ont = @@onts.first @@ -42,6 +42,7 @@ def test_filtered_list end def test_search_custom_onts + skip "Test is not consistent, need to be fixed to work all the time" # Make sure group and non-group onts are in the search index get "/search?q=a*&pagesize=500&apikey=#{@@non_custom_user.apikey}" assert last_response.ok? @@ -56,14 +57,16 @@ def test_search_custom_onts assert results.all? {|r| @@custom_ont_ids.include?(r["links"]["ontology"])} end + private + def self._create_user(username = nil) username ||= "testuser" u = LinkedData::Models::User.new({ - username: username, - email: "#{username}@example.com", - password: "a_password" - }) - u.save + username: username, + email: "#{username}@example.com", + password: "a_password" + }) + u.save rescue binding.pry u end end From 8624e269886572124141289c501e4ed16b83afb1 Mon Sep 17 00:00:00 2001 From: mdorf Date: Fri, 30 Jan 2026 10:20:40 -0800 Subject: [PATCH 056/173] fixed test_default_multilingual test because language :none changed to @none in GOO --- test/controllers/test_classes_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/test_classes_controller.rb b/test/controllers/test_classes_controller.rb index ca8d64f2d..f4545bc9f 100644 --- a/test/controllers/test_classes_controller.rb +++ b/test/controllers/test_classes_controller.rb @@ -525,7 +525,7 @@ def test_class_page_with_metric_count assert page_response["collection"].length == 0 end - def test_multilingual + def test_default_multilingual ont = Ontology.find("TEST-ONT-0").include(:acronym).first sub = ont.latest_submission sub.bring_remaining @@ -605,7 +605,7 @@ def test_multilingual assert last_response.ok? page_response = MultiJson.load(last_response.body) - assert_equal 'Research Lab Management', page_response["prefLabel"]["none"] + assert_equal 'Research Lab Management', page_response.dig("prefLabel", "none") || page_response.dig("prefLabel", "@none") assert_equal 'Gestion du laboratoire de recherche', page_response["prefLabel"]["fr"] assert_equal 'Gestione del laboratorio di ricerca', page_response["prefLabel"]["it"] end From 546e92ac2631a9b5bc39be7046e5164762a3fcc1 Mon Sep 17 00:00:00 2001 From: mdorf Date: Sun, 1 Feb 2026 00:22:32 -0800 Subject: [PATCH 057/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ef6b04631..2dca4fea8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 256afce837da44d31e8da1e08a6c7c56bbd1820f + revision: 824872a443b074bb7ad85f7fa57274fdb2e2b39a branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -311,7 +311,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0113) + mime-types-data (3.2026.0127) mini_mime (1.1.5) minitest (6.0.1) prism (~> 1.5) From 08b0ed0d226f92a82d586085c79bf4848b1d6572 Mon Sep 17 00:00:00 2001 From: mdorf Date: Mon, 2 Feb 2026 15:48:45 -0800 Subject: [PATCH 058/173] updated test_default_multilingual unit test to correctly test for french prefLabels --- Gemfile.lock | 4 ++-- test/controllers/test_classes_controller.rb | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2dca4fea8..bdd1fc3b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 824872a443b074bb7ad85f7fa57274fdb2e2b39a + revision: 53a0d4c3bbe56f7a8caed9fab736f509ebecb61d branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 7373727da30d09f7556c550798ed14bed0e99383 + revision: d9aefd5a9bff4fcb40d687b16b25e171457deeeb branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/test/controllers/test_classes_controller.rb b/test/controllers/test_classes_controller.rb index f4545bc9f..d02e94766 100644 --- a/test/controllers/test_classes_controller.rb +++ b/test/controllers/test_classes_controller.rb @@ -560,8 +560,7 @@ def test_default_multilingual assert last_response.ok? page_response = MultiJson.load(last_response.body) # show french value as specified in submission naturalLanguage - assert_equal 'Gestion des échantillons biologiques', page_response["prefLabel"] - + assert_equal 'Gestion des Bioéchantillons', page_response["prefLabel"] sub.naturalLanguage = [] sub.save @@ -584,7 +583,6 @@ def test_default_multilingual page_response = MultiJson.load(last_response.body) # show Japanese value as specified in submission naturalLanguage assert_equal 'カタログ', page_response["prefLabel"] - sub.naturalLanguage = [] sub.save From 72e2f1eb6064ad29cb962684af0e36ba8afd7e9a Mon Sep 17 00:00:00 2001 From: mdorf Date: Mon, 2 Feb 2026 18:49:58 -0800 Subject: [PATCH 059/173] Gemfile.lock update --- Gemfile.lock | 10 +++++----- config/environments/test.rb | 4 ---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index bdd1fc3b1..10ead5bf9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: fa8f225e6c3d3df4bdc03029b1598201d079b387 + revision: a3f45dc497ec8188872a3ed15cdade44d5f3fd64 branch: chore/rdf3-compat specs: ncbo_annotator (0.0.1) @@ -367,7 +367,7 @@ GEM racc pony (1.13.1) mail (>= 2.0) - prism (1.8.0) + prism (1.9.0) pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) @@ -414,7 +414,7 @@ GEM rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.3) + redis-client (0.26.4) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -435,7 +435,7 @@ GEM rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) - rubocop (1.82.1) + rubocop (1.84.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -443,7 +443,7 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.48.0, < 2.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) rubocop-ast (1.49.0) diff --git a/config/environments/test.rb b/config/environments/test.rb index 61d5ef509..0080342ad 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -16,12 +16,8 @@ MGREP_DICTIONARY_FILE = ENV.include?("MGREP_DICTIONARY_FILE") ? ENV["MGREP_DICTIONARY_FILE"] : "./test/data/dictionary.txt" MGREP_HOST = ENV.include?("MGREP_HOST") ? ENV["MGREP_HOST"] : "localhost" - - -# MGREP_PORT = ENV.include?("MGREP_PORT") ? ENV["MGREP_PORT"] : 55556 MGREP_PORT = ENV.include?("MGREP_PORT") ? ENV["MGREP_PORT"] : 55555 - REDIS_GOO_CACHE_HOST = ENV.include?("REDIS_GOO_CACHE_HOST") ? ENV["REDIS_GOO_CACHE_HOST"] : "localhost" REDIS_HTTP_CACHE_HOST = ENV.include?("REDIS_HTTP_CACHE_HOST") ? ENV["REDIS_HTTP_CACHE_HOST"] : "localhost" REDIS_PERSISTENT_HOST = ENV.include?("REDIS_PERSISTENT_HOST") ? ENV["REDIS_PERSISTENT_HOST"] : "localhost" From 3f720c337d4022736d4e48ad2eebdec7860682dd Mon Sep 17 00:00:00 2001 From: mdorf Date: Mon, 2 Feb 2026 23:23:55 -0800 Subject: [PATCH 060/173] fixed a failing unit test, test_default_multilingual --- Gemfile | 2 +- Gemfile.lock | 6 +++--- test/controllers/test_classes_controller.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 3f031ea57..4f3cc375a 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,7 @@ gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/rdf3-compat' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-rdf3-compat' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' diff --git a/Gemfile.lock b/Gemfile.lock index 10ead5bf9..646187c38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,8 +18,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: a3f45dc497ec8188872a3ed15cdade44d5f3fd64 - branch: chore/rdf3-compat + revision: 33e412fb08b7c6919543785c94016a1ab0113cfd + branch: chore/ruby3.2-rdf3-compat specs: ncbo_annotator (0.0.1) goo @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: d9aefd5a9bff4fcb40d687b16b25e171457deeeb + revision: 77a98064f91c7cce5d89e31e3b3768dbc9a441a5 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/test/controllers/test_classes_controller.rb b/test/controllers/test_classes_controller.rb index d02e94766..bee4d4bed 100644 --- a/test/controllers/test_classes_controller.rb +++ b/test/controllers/test_classes_controller.rb @@ -551,7 +551,7 @@ def test_default_multilingual assert last_response.ok? page_response = MultiJson.load(last_response.body) # does not contain a value in english show the generated one - assert_equal 'Gene_Therapy', page_response["prefLabel"] + assert_equal 'Gene Therapy', page_response["prefLabel"] # prefLabel is present in the ontology language sub.naturalLanguage = ['fr'] From a9508b9b1f5b4f53633d5528b17b947f5a502d76 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 3 Feb 2026 09:00:31 -0800 Subject: [PATCH 061/173] removed minitest-fail-fast gem, as minitest 6 already includes --fail-fast flag --- Gemfile | 1 - Gemfile.lock | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 4f3cc375a..ef4fdd38a 100644 --- a/Gemfile +++ b/Gemfile @@ -84,7 +84,6 @@ group :test do gem 'minitest-hooks' gem 'minitest-stub_any_instance' gem 'minitest-reporters' - gem 'minitest-fail-fast' gem 'rack-test' gem 'simplecov', require: false gem 'simplecov-cobertura' # for codecov.io diff --git a/Gemfile.lock b/Gemfile.lock index 646187c38..4cde14f7e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 33e412fb08b7c6919543785c94016a1ab0113cfd + revision: 9cdb46a6b94c1bedb7a4dbab456888459217b7be branch: chore/ruby3.2-rdf3-compat specs: ncbo_annotator (0.0.1) @@ -279,7 +279,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.18.0) + json (2.18.1) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -315,8 +315,6 @@ GEM mini_mime (1.1.5) minitest (6.0.1) prism (~> 1.5) - minitest-fail-fast (0.2.0) - minitest (>= 5.0, < 7) minitest-hooks (1.5.3) minitest (> 5.3) minitest-reporters (1.7.1) @@ -545,7 +543,6 @@ DEPENDENCIES json-ld (~> 3.2.0) json-schema minitest - minitest-fail-fast minitest-hooks minitest-reporters minitest-stub_any_instance From 092df330b8efdeefb67ff61bf0c9035a2fbf9846 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 3 Feb 2026 12:07:09 -0800 Subject: [PATCH 062/173] Gemfile.lock update --- Gemfile.lock | 196 ++++++++++++++++++++++++++++++++++++++++++++- docker-compose.yml | 4 +- 2 files changed, 196 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4cde14f7e..af3aa57d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 77a98064f91c7cce5d89e31e3b3768dbc9a441a5 + revision: 139bb2e327b576c4ec374ad6ceec553cd0de8d11 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -586,5 +586,197 @@ DEPENDENCIES webmock webrick +CHECKSUMS + activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae + addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + airbrussh (1.6.0) sha256=7e2cf581f2319d2c2b2b672c9fc486efb4dfcfed4bd2dadbef5f10b8b2a000d0 + ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bcp47_spec (0.2.1) sha256=3fd62edf96c126bd9624e4319ac74082a966081859d1ee0ef3c3041640a37810 + bcrypt (3.1.21) sha256=5964613d750a42c7ee5dc61f7b9336fb6caca429ba4ac9f2011609946e4a2dcf + bcrypt_pbkdf (1.1.2) sha256=c2414c23ce66869b3eb9f643d6a3374d8322dfb5078125c82792304c10b94cf6 + bcrypt_pbkdf (1.1.2-arm64-darwin) sha256=afdd6feb6ed5a97b8e44caacb3f2d641b98af78e6a516d4a3520b69af5cf9fea + bcrypt_pbkdf (1.1.2-x86_64-darwin) sha256=35f5639d0058e6c2cc2f856f9c0b14080543268d3047abe6bc81c513093caa0e + bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e + capistrano (3.20.0) sha256=0113e58dda99add0342e56a244f664734c59f442c5ed734f5303b0b559b479c9 + capistrano-bundler (2.2.0) sha256=47b4cf2ea17ea132bb0a5cabc5663443f5190a54f4da5b322d04e1558ff1468c + capistrano-locally (0.3.0) sha256=ad44252f19641e8dd980f7cb0241e9ac11919b1f4cbdb642d272a6d0edcb84eb + capistrano-rbenv (2.2.0) sha256=3c8f39b7c624f3806630dcb475484bb3579aef07a40efe85089d83f64b0c35f5 + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a + crack (0.4.5) sha256=798416fb29b8c9f655d139d5559169b39c4a0a3b8f8f39b7f670eec1af9b21b3 + dante (0.2.0) sha256=939776f04b4d253ffbbcf53341631aa2ee6e6cf314dedade2e60ac43b40a6fe6 + date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 + docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 + down (5.4.2) sha256=516e5e01e7a96214a7e2cd155aac6f700593038ae6c857c0f4a05413b1c58acf + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 + faraday (2.14.0) sha256=8699cfe5d97e55268f2596f9a9d5a43736808a943714e3d9a53e6110593941cd + faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad + faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c + faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe + ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c + ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 + ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 + ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 + ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 + ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f + ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 + ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 + ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 + ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f + ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 + gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 + get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba + goo (0.0.2) + google-analytics-data (0.7.2) sha256=5e4bf6dc575c7725c2b32541725749890a88e0a64ff0ad7e8a73f75ad5a1bbc9 + google-analytics-data-v1beta (0.17.0) sha256=1145d30d794bcf6bf8b723140a0ee2c445e740b82cf4051a31d992e7393168a6 + google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf + google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7 + google-cloud-errors (1.5.0) sha256=b56be28b8c10628125214dde571b925cfcebdbc58619e598250c37a2114f7b4b + google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b + google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 + google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 + google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c + google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 + google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 + google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 + googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe + googleapis-common-protos-types (1.20.0) sha256=5e374b06bcfc7e13556e7c0d87b99f1fa3d42de6396a1de3d8fc13aefb4dd07f + googleauth (1.16.1) sha256=36776bce9d55d8c1a0c6638c939b000dcee5954ca5b728f06ec4c2df4a46709c + grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb + grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 + grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 + grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 + grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 + grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be + haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c + hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 + htmlentities (4.4.2) sha256=bbafbdf69f2eca9262be4efef7e43e6a1de54c95eb600f26984f71d2fe96c5c3 + http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 + http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 + i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986 + json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef + json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc + json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 + jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 + kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + libxml-ruby (5.0.5) sha256=f1bc07152982df555d70159a694ee2a53539de2cdad4b3c8a447fbb15e7e4e9a + link_header (0.0.8) sha256=15c65ce43b29f739b30d05e5f25c22c23797e89cf6f905dbb595fb4c70cb55f9 + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 + mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 + mime-types-data (3.2026.0127) sha256=4a58692436a987ad930e75bf8f24da7e627acfa0d06e1720aa514791b4c7d12b + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb + minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 + minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c + minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 + mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 + multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 + mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22 + ncbo_annotator (0.0.1) + ncbo_cron (0.0.1) + ncbo_ontology_recommender (0.0.1) + net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 + net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 + net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 + net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6 + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d + net-sftp (4.0.0) sha256=65bb91c859c2f93b09826757af11b69af931a3a9155050f50d1b06d384526364 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 + netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f + oj (3.16.13) sha256=b114bcb83ef884f1736b3112108f77cf9ca90aa8111a775318cc5d7a6a1e0303 + omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e + ontologies_linked_data (0.0.1) + os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f + ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 + pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 + parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 + pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e + public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 + rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 + rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2 + rack-cache (1.17.0) sha256=49592f3ef2173b0f5524df98bb801fb411e839869e7ce84ac428dc492bf0eb90 + rack-contrib (2.5.0) sha256=51bd2ce82b8a3270f9173130c4cdaea72aab8b03dce8cd6af1c4344d84a32d02 + rack-cors (3.0.0) sha256=7b95be61db39606906b61b83bd7203fa802b0ceaaad8fcb2fef39e097bf53f68 + rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78 + rack-post-body-to-params (0.1.8) + rack-protection (4.2.1) + rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 + rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + raindrops (0.20.1) sha256=aa0eb9ff6834f2d9e232ba688bd49cb30be893bc5a3452e74722c94c1fab4730 + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + rdf (3.3.1) sha256=dda6a2c95198915fc63d66ee270e35d4a76d431720747a2cf97ecd92062fa150 + rdf-raptor (3.3.0) + rdf-rdfxml (3.3.0) sha256=11647f6111b97b6a9b82413bd9810d4bb5524aa7dd06b3c1330bf58ec3aa6a9a + rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b + rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 + redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae + redis-client (0.26.4) sha256=3ad70beff5da2653e02dfeae996e7d8d7147a558da12b16b2282ad345e4c7120 + redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 + redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 + regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb + rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b + rubocop (1.84.1) sha256=14cc626f355141f5a2ef53c10a68d66b13bb30639b26370a76559096cc6bcc1a + rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 + ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef + rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c + rufus-scheduler (2.0.24) sha256=cf1b6ebe4835368d48e5ec9fd275327ffb03fc566fd1609744b76749b32ad446 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + shotgun (0.9) + signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b + simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 + simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5 + simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 + simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080 + sinatra-contrib (4.2.1) + sparql-client (3.2.2) + sshkit (1.25.0) sha256=c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744 + systemu (2.6.5) sha256=01f7d014b1453b28e5781e15c4d7d63fc9221c29b174b7aae5253207a75ab33e + temple (0.10.4) sha256=b7a1e94b6f09038ab0b6e4fe0126996055da2c38bec53a8a336f075748fff72c + tilt (2.7.0) sha256=0d5b9ba69f6a36490c64b0eee9f6e9aad517e20dcc848800a06eb116f08c6ab3 + time (0.4.2) sha256=f324e498c3bde9471d45a7d18f874c27980e9867aa5cfca61bebf52262bc3dab + timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + unicorn (6.1.0) sha256=45dd987add4c2b084c1880a68373af42797a704ad7441faff9b14b4982aa0fc0 + unicorn-worker-killer (0.4.5) sha256=fc3c5dae71566c9e2a165dfbf75664f7bc16fec20251a1d09c3375ffe58b3991 + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 + uuid (2.3.9) sha256=aec0cf592053cd6e07c13c1ef94c440aba705f22eb1ee767b39631f2760124d7 + webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 + webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 + BUNDLED WITH - 2.6.3 + 4.0.5 diff --git a/docker-compose.yml b/docker-compose.yml index 8f70e7196..303be0220 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,8 +16,8 @@ x-app: &app REDIS_HTTP_CACHE_HOST: redis-ut REDIS_PERSISTENT_HOST: redis-ut REDIS_PORT: 6379 - SOLR_TERM_SEARCH_URL: http://solr-ut:8983/solr/term_search_core1 - SOLR_PROP_SEARCH_URL: http://solr-ut:8983/solr/prop_search_core1 + SOLR_TERM_SEARCH_URL: http://solr-ut:8983/solr + SOLR_PROP_SEARCH_URL: http://solr-ut:8983/solr MGREP_HOST: mgrep-ut MGREP_PORT: 55556 stdin_open: true From 6d58a85d9932cc03f7d1bbb11eaa695320bfb961 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 3 Feb 2026 12:21:42 -0800 Subject: [PATCH 063/173] Gemfile.lock update --- Gemfile | 4 ++-- Gemfile.lock | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index ef4fdd38a..0933e0553 100644 --- a/Gemfile +++ b/Gemfile @@ -52,9 +52,9 @@ gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-rdf3-compat' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index af3aa57d1..8bdf51ceb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,8 +18,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 9cdb46a6b94c1bedb7a4dbab456888459217b7be - branch: chore/ruby3.2-rdf3-compat + revision: 30ae1929a038650fb5685b075d960ff8a4a96dba + branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) goo @@ -47,8 +47,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 76d9516adc3c5c6d5c95f21f307bdd60eb3e0acd - branch: develop + revision: 7e81eb9ac92b98ee72fc5e05a63b99292f0de5f9 + branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) goo @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 139bb2e327b576c4ec374ad6ceec553cd0de8d11 + revision: 8c2040180b364921698ccc7810bb26ea54e6f701 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) From 88a8aa1f351e4bccd1734eaa7e2dea66981e6065 Mon Sep 17 00:00:00 2001 From: mdorf Date: Tue, 3 Feb 2026 13:42:04 -0800 Subject: [PATCH 064/173] Gemfile.lock update --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 0933e0553..524a0f0d0 100644 --- a/Gemfile +++ b/Gemfile @@ -53,7 +53,7 @@ gem 'pandoc-ruby' gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ruby3.2-minitest6-compat' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' diff --git a/Gemfile.lock b/Gemfile.lock index 8bdf51ceb..97edde6d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,8 +29,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: d3625bc7769f1c8cfcc4063ac9478b0723ed4686 - branch: develop + revision: 160404bc5e0dcd1ef0ab06883b19c63a3aae6c9d + branch: chore/ruby3.2-minitest6-compat specs: ncbo_cron (0.0.1) dante @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 8c2040180b364921698ccc7810bb26ea54e6f701 + revision: 9282060c02a6ca242d9c4652e3f66799d3475d43 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) From bea5b8f055899fede779508cf3f47d758b57b976 Mon Sep 17 00:00:00 2001 From: mdorf Date: Wed, 4 Feb 2026 22:21:32 -0800 Subject: [PATCH 065/173] Gemfile.lock update --- Gemfile | 2 +- Gemfile.lock | 38 +++++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Gemfile b/Gemfile index 524a0f0d0..daf59ce67 100644 --- a/Gemfile +++ b/Gemfile @@ -53,7 +53,7 @@ gem 'pandoc-ruby' gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ruby3.2-minitest6-compat' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ontoportal-lirmm-goo-compat' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' diff --git a/Gemfile.lock b/Gemfile.lock index 97edde6d8..3a02ed2fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 53a0d4c3bbe56f7a8caed9fab736f509ebecb61d + revision: 75e1df5ce04d877f2d2eb3a4e93686c4c12339b9 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 30ae1929a038650fb5685b075d960ff8a4a96dba + revision: 78f53234d52f4938047972425d1cc58933882f86 branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -29,8 +29,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 160404bc5e0dcd1ef0ab06883b19c63a3aae6c9d - branch: chore/ruby3.2-minitest6-compat + revision: 81f118d2f108a3e98019ea87e93286d15376332c + branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) dante @@ -43,11 +43,11 @@ GIT ncbo_annotator ontologies_linked_data redis - rufus-scheduler (~> 2.0.24) + rufus-scheduler (~> 3.9) GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 7e81eb9ac92b98ee72fc5e05a63b99292f0de5f9 + revision: b0a45a25d901bd43e28d9e2ca667a5c9a299c86e branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9282060c02a6ca242d9c4652e3f66799d3475d43 + revision: abb93105158193d348daba0e1b0e005174e14061 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -183,6 +183,8 @@ GEM addressable (~> 2.8) drb (2.2.3) ed25519 (1.4.0) + et-orbi (1.4.0) + tzinfo faraday (2.14.0) faraday-net_http (>= 2.0, < 3.5) json @@ -204,6 +206,9 @@ GEM ffi (1.17.3-x86_64-darwin) ffi (1.17.3-x86_64-linux-gnu) ffi (1.17.3-x86_64-linux-musl) + fugit (1.12.1) + et-orbi (~> 1.4) + raabro (~> 1.4) gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) @@ -311,7 +316,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0127) + mime-types-data (3.2026.0203) mini_mime (1.1.5) minitest (6.0.1) prism (~> 1.5) @@ -350,9 +355,8 @@ GEM net-protocol net-ssh (7.3.0) netrc (0.11.0) - oj (3.16.13) + oj (3.16.14) bigdecimal (>= 3.0) - ostruct (>= 0.2) omni_logger (0.1.4) logger os (1.1.4) @@ -371,6 +375,7 @@ GEM method_source (~> 1.0) reline (>= 0.6.0) public_suffix (7.0.2) + raabro (1.4.0) racc (1.8.1) rack (3.2.4) rack-accept (0.4.5) @@ -451,8 +456,8 @@ GEM ruby-xxHash (0.4.0.2) ruby2_keywords (0.0.5) rubyzip (3.2.2) - rufus-scheduler (2.0.24) - tzinfo (>= 0.3.22) + rufus-scheduler (3.9.2) + fugit (~> 1.1, >= 1.11.1) securerandom (0.4.1) signet (0.21.0) addressable (~> 2.8) @@ -616,6 +621,7 @@ CHECKSUMS down (5.4.2) sha256=516e5e01e7a96214a7e2cd155aac6f700593038ae6c857c0f4a05413b1c58acf drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 + et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc faraday (2.14.0) sha256=8699cfe5d97e55268f2596f9a9d5a43736808a943714e3d9a53e6110593941cd faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c @@ -631,6 +637,7 @@ CHECKSUMS ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 + fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba goo (0.0.2) @@ -677,7 +684,7 @@ CHECKSUMS mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0127) sha256=4a58692436a987ad930e75bf8f24da7e627acfa0d06e1720aa514791b4c7d12b + mime-types-data (3.2026.0203) sha256=54353d693af028847391c28361c07d4b8b689cad78c3e1cc272fb1205c6d2a2f mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 @@ -700,7 +707,7 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f - oj (3.16.13) sha256=b114bcb83ef884f1736b3112108f77cf9ca90aa8111a775318cc5d7a6a1e0303 + oj (3.16.14) sha256=94da4f737f5c67aa52e2231fe2adb5257c0c95822fe7e3793a07c69542362571 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f @@ -713,6 +720,7 @@ CHECKSUMS prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 @@ -751,7 +759,7 @@ CHECKSUMS ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c - rufus-scheduler (2.0.24) sha256=cf1b6ebe4835368d48e5ec9fd275327ffb03fc566fd1609744b76749b32ad446 + rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 shotgun (0.9) signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b From ea570ede845f14b9add57718e36894844def0ab2 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 13:36:15 -0800 Subject: [PATCH 066/173] fixed the warning: detected duplicate key creator in JSON object. This will raise an error in json 3.0 --- test/controllers/test_projects_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/controllers/test_projects_controller.rb b/test/controllers/test_projects_controller.rb index 8083a75c3..de6e4bc49 100644 --- a/test/controllers/test_projects_controller.rb +++ b/test/controllers/test_projects_controller.rb @@ -1,4 +1,3 @@ -require_relative '../test_case' require 'json-schema' class TestProjectsController < TestCase @@ -107,7 +106,7 @@ def test_project_create_failure _project_delete(@p.acronym) # Fail PUT for any project with required missing data. username = 'user_does_not_exist' - @projectParams['creator'] = username + @projectParams[:creator] = username put "/projects/#{@p.acronym}", MultiJson.dump(@projectParams), "CONTENT_TYPE" => "application/json" _response_status(422, last_response) _project_get_failure(@p.acronym) From 0ae6948dc7a435eb9a1a6b4bf75877fffca08e8a Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 14:00:46 -0800 Subject: [PATCH 067/173] re-enabled the test test_search_models_controller/test_search_data. It appears to run consistently now --- Gemfile.lock | 2 +- .../test_search_models_controller.rb | 148 +++++++++--------- test/test_case.rb | 3 - 3 files changed, 72 insertions(+), 81 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3a02ed2fa..fe104e46c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 81f118d2f108a3e98019ea87e93286d15376332c + revision: 86b3067c1c5da9b4cdc66388d0602e0932b09025 branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index 16cbecc0b..b62c3c09b 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -38,15 +38,15 @@ def test_collection_schema end def test_collection_search - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: false, - acronym: "BROSEARCHTEST", - name: "BRO Search Test", - file_path: "./test/data/ontology_files/BRO_v3.2.owl", - ont_count: 1, - submission_count: 1, - ontology_type: "VALUE_SET_COLLECTION" - }) + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) collection = 'ontology_metadata' post "/admin/search/collections/#{collection}/search", {q: ""} @@ -56,27 +56,26 @@ def test_collection_search end def test_search_security - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, - acronym: "BROSEARCHTEST", - name: "BRO Search Test", - file_path: "./test/data/ontology_files/BRO_v3.2.owl", - ont_count: 1, - submission_count: 1, - ontology_type: "VALUE_SET_COLLECTION" - }) - - count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, - acronym: "MCCLSEARCHTEST", - name: "MCCL Search Test", - file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", - ont_count: 1, - submission_count: 1 - }) - + _, _, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) subs = LinkedData::Models::OntologySubmission.all subs.each do |s| @@ -139,25 +138,24 @@ def test_search_security end def test_ontology_metadata_search - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: false, - acronym: "BROSEARCHTEST", - name: "BRO Search Test", - file_path: "./test/data/ontology_files/BRO_v3.2.owl", - ont_count: 1, - submission_count: 1, - ontology_type: "VALUE_SET_COLLECTION" - }) - - count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: false, - acronym: "MCCLSEARCHTEST", - name: "MCCL Search Test", - file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", - ont_count: 1, - submission_count: 1 - }) - + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: false, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) # Search ACRONYM ## full word get '/search/ontologies?query=BROSEARCHTEST-0' @@ -364,29 +362,26 @@ def test_ontology_metadata_filters end def test_search_data - skip "Test is not consistent, need to be fixed to work all the time" - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, - acronym: "BROSEARCHTEST", - name: "BRO Search Test", - file_path: "./test/data/ontology_files/BRO_v3.2.owl", - ont_count: 1, - submission_count: 1, - ontology_type: "VALUE_SET_COLLECTION" - }) - - count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, - acronym: "MCCLSEARCHTEST", - name: "MCCL Search Test", - file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", - ont_count: 1, - submission_count: 1 - }) - - + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, index_all_data: true, generate_missing_labels: false}, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) subs = LinkedData::Models::OntologySubmission.all count = [] subs.each do |s| @@ -395,11 +390,10 @@ def test_search_data .to_i end - # TO-DO: Fix this test as it's not consistent - # get "/search/ontologies/content?q=*" - # assert last_response.ok? - # res = MultiJson.load(last_response.body) - # assert_equal count.sum, res['totalCount'] + get "/search/ontologies/content?q=*" + assert last_response.ok? + res = MultiJson.load(last_response.body) + assert_equal count.sum, res['totalCount'] get "/search/ontologies/content?q=*&ontologies=MCCLSEARCHTEST-0,BROSEARCHTEST-0" assert last_response.ok? diff --git a/test/test_case.rb b/test/test_case.rb index f793932bc..0bffc0221 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -143,8 +143,6 @@ def _run_suite(suite, type) class TestCase < AppUnit include Rack::Test::Methods - - def app Sinatra::Application end @@ -236,7 +234,6 @@ def self.delete_user(username) User.find(username).first&.delete end - def self.make_admin(user) user.bring_remaining user.role = [LinkedData::Models::Users::Role.find(LinkedData::Models::Users::Role::ADMIN).first] From ab55e41bca21097f9908e88df5d3c4db4f0b2ef2 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 14:09:54 -0800 Subject: [PATCH 068/173] fixed a missing require --- test/controllers/test_projects_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/controllers/test_projects_controller.rb b/test/controllers/test_projects_controller.rb index de6e4bc49..cd479f6f9 100644 --- a/test/controllers/test_projects_controller.rb +++ b/test/controllers/test_projects_controller.rb @@ -1,3 +1,4 @@ +require_relative '../test_case' require 'json-schema' class TestProjectsController < TestCase From 71e136744e67f866971767874475bef312839d06 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 15:23:01 -0800 Subject: [PATCH 069/173] fixed docker-compose vars --- Gemfile.lock | 2 +- docker-compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index fe104e46c..581048c35 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 75e1df5ce04d877f2d2eb3a4e93686c4c12339b9 + revision: 13a8559a2346cc8320d7d36046646907bfa8a27c branch: ontoportal-lirmm-development specs: goo (0.0.2) diff --git a/docker-compose.yml b/docker-compose.yml index 303be0220..aa1145240 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ x-app: &app build: context: . args: - RUBY_VERSION: '3.1' + RUBY_VERSION: '3.2' # Increase the version number in the image tag every time Dockerfile or its arguments is changed image: ontologies_api:0.0.6 environment: &env @@ -122,7 +122,7 @@ services: retries: 5 agraph-ut: - image: franzinc/agraph:v8.1.0 + image: franzinc/agraph:v8.3.1 platform: linux/amd64 environment: - AGRAPH_SUPER_USER=test From 7b81f9aeeb6bcf5914dd133867c5770ebe16f30b Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 21:15:48 -0800 Subject: [PATCH 070/173] added ability to return unmapped attributes for properties --- Gemfile.lock | 8 +- controllers/properties_controller.rb | 13 +-- .../test_ontology_submissions_controller.rb | 1 - .../controllers/test_properties_controller.rb | 83 +++++++++++++------ 4 files changed, 70 insertions(+), 35 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 581048c35..9b1f42b5c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 78f53234d52f4938047972425d1cc58933882f86 + revision: e4be8480530700a6a1bd165b03cc6a331a029077 branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -29,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 86b3067c1c5da9b4cdc66388d0602e0932b09025 + revision: 84b63df9694801667f845677a131ced48b92e640 branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -47,7 +47,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: b0a45a25d901bd43e28d9e2ca667a5c9a299c86e + revision: 2ef0e6f86e634d06a20ebb3d12b4160470eface1 branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: abb93105158193d348daba0e1b0e005174e14061 + revision: b731028f1a6781ff2254238486c5b057c39f4596 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/controllers/properties_controller.rb b/controllers/properties_controller.rb index f98e90168..82313355b 100644 --- a/controllers/properties_controller.rb +++ b/controllers/properties_controller.rb @@ -24,7 +24,8 @@ class PropertiesController < ApplicationController get '/:property' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + bring_unmapped = bring_unmapped?(includes_param) + p = ont.property(prop, submission, display_all_attributes: bring_unmapped) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? reply 200, p end @@ -51,7 +52,7 @@ class PropertiesController < ApplicationController get '/:property/tree' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + p = ont.property(prop, submission, display_all_attributes: false) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? root_tree = p.tree @@ -79,7 +80,7 @@ class PropertiesController < ApplicationController get '/:property/ancestors' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + p = ont.property(prop, submission, display_all_attributes: false) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? ancestors = p.ancestors p.class.in(submission).models(ancestors).include(:label, :definition).all @@ -91,7 +92,7 @@ class PropertiesController < ApplicationController get '/:property/descendants' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + p = ont.property(prop, submission, display_all_attributes: false) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? descendants = p.descendants p.class.in(submission).models(descendants).include(:label, :definition).all @@ -103,7 +104,7 @@ class PropertiesController < ApplicationController get '/:property/parents' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + p = ont.property(prop, submission, display_all_attributes: false) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? p.bring(:parents) @@ -120,7 +121,7 @@ class PropertiesController < ApplicationController get '/:property/children' do prop = params[:property] ont, submission = get_ontology_and_submission - p = ont.property(prop, submission) + p = ont.property(prop, submission, display_all_attributes: false) error 404, "Property #{prop} not found in ontology #{ont.id.to_s}" if p.nil? p.bring(:children) diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb index 5b185a089..a4df6becf 100644 --- a/test/controllers/test_ontology_submissions_controller.rb +++ b/test/controllers/test_ontology_submissions_controller.rb @@ -494,7 +494,6 @@ def test_submissions_pagination_filter get "/submissions?page=1&pagesize=100&name=#{name_search}" assert last_response.ok? submissions = MultiJson.load(last_response.body) - binding.pry unless submissions['collection'].length.eql?(count) assert_equal count, submissions['collection'].length end diff --git a/test/controllers/test_properties_controller.rb b/test/controllers/test_properties_controller.rb index 6aac347df..33e9b26a2 100644 --- a/test/controllers/test_properties_controller.rb +++ b/test/controllers/test_properties_controller.rb @@ -3,26 +3,26 @@ class TestPropertiesController < TestCase def before_suite - count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options:{process_rdf: true, extract_metadata: false}, - acronym: "BROSEARCHTEST", - name: "BRO Search Test", - file_path: "./test/data/ontology_files/BRO_v3.2.owl", - ont_count: 1, - submission_count: 1, - ontology_type: "VALUE_SET_COLLECTION" - }) - - count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ - process_submission: true, - process_options:{process_rdf: true, extract_metadata: true}, - acronym: "MCCLSEARCHTEST", - name: "MCCL Search Test", - file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", - ont_count: 1, - submission_count: 1 - }) + _, _, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options:{process_rdf: true, extract_metadata: false}, + acronym: "BROSEARCHTEST", + name: "BRO Search Test", + file_path: "./test/data/ontology_files/BRO_v3.2.owl", + ont_count: 1, + submission_count: 1, + ontology_type: "VALUE_SET_COLLECTION" + }) + + _, _, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options:{process_rdf: true, extract_metadata: true}, + acronym: "MCCLSEARCHTEST", + name: "MCCL Search Test", + file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl", + ont_count: 1, + submission_count: 1 + }) @@ontologies = bro.concat(mccl) @@acronyms = @@ontologies.map { |ont| ont.bring_remaining; ont.acronym } end @@ -47,14 +47,33 @@ def test_single_property get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fbioontology.org%2Fontologies%2FBiomedicalResourceOntology.owl%23Originator" assert last_response.ok? results = MultiJson.load(last_response.body) + assert results.is_a?(Hash) assert_equal ["Originator"], results["label"] assert_equal "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Originator", results["@id"] + assert results.key?('range') + assert results.key?('domain') get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fbioontology.org%2Fontologies%2FBiomedicalResourceOntology.owl%23DummyProp" assert_equal 404, last_response.status end + def test_single_property_all_attributes + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fbioontology.org%2Fontologies%2FBiomedicalResourceOntology.owl%23Originator?display=all" + assert last_response.ok? + results = MultiJson.load(last_response.body) + + assert_equal ["Originator"], results["label"] + assert results.key?('range') + assert results.key?('domain') + + assert_equal results["properties"]["http://www.w3.org/2000/01/rdf-schema#comment"], ["Originator of a class"] + assert_equal results["properties"]["http://www.w3.org/2004/02/skos/core#prefLabel"], ["Originator"] + assert_equal results["properties"]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], ["http://www.w3.org/2002/07/owl#DatatypeProperty"] + assert_equal results["properties"]["http://www.w3.org/2000/01/rdf-schema#domain"], ["http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Algorithm"] + assert_equal results["properties"]["http://www.w3.org/2000/01/rdf-schema#label"], ["Originator"] + end + def test_property_roots get "/ontologies/#{@@acronyms.first}/properties/roots" assert last_response.ok? @@ -63,14 +82,15 @@ def test_property_roots # count object properties opr = pr.select { |p| p["@type"] == "http://www.w3.org/2002/07/owl#ObjectProperty" } - assert_equal 18, opr.length + assert_includes [18, 13], opr.length # count datatype properties dpr = pr.select { |p| p["@type"] == "http://www.w3.org/2002/07/owl#DatatypeProperty" } - assert_equal 32, dpr.length + assert_includes [32, 31], dpr.length # count annotation properties apr = pr.select { |p| p["@type"] == "http://www.w3.org/2002/07/owl#AnnotationProperty" } - assert_equal 12, apr.length + assert_includes [12, 8], apr.length # check for non-root properties + assert_empty pr.select { |p| ["http://www.w3.org/2004/02/skos/core#broaderTransitive", "http://www.w3.org/2004/02/skos/core#topConceptOf", "http://www.w3.org/2004/02/skos/core#relatedMatch", @@ -100,6 +120,9 @@ def test_property_roots end def test_property_tree + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23topConceptOf" + return unless last_response.ok? # depending if owlapi import SKOS + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23topConceptOf/tree" assert last_response.ok? pr = MultiJson.load(last_response.body) @@ -131,6 +154,9 @@ def test_property_tree end def test_property_ancestors + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23exactMatch" + return unless last_response.ok? + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23exactMatch/ancestors" assert last_response.ok? an = MultiJson.load(last_response.body) @@ -145,6 +171,9 @@ def test_property_ancestors end def test_property_descendants + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23note" + return unless last_response.ok? # depending if owlapi import SKOS + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23note/descendants" assert last_response.ok? dn = MultiJson.load(last_response.body) @@ -162,10 +191,13 @@ def test_property_descendants dn = MultiJson.load(last_response.body) assert_equal 2, dn.length assert_equal ["http://www.semanticweb.org/ontologies/2009/9/12/Ontology1255323704656.owl#overExpress", - "http://www.semanticweb.org/ontologies/2009/9/12/Ontology1255323704656.owl#underExpress"].sort, dn.map { |d| d["@id"] }.sort + "http://www.semanticweb.org/ontologies/2009/9/12/Ontology1255323704656.owl#underExpress"].sort, dn.map { |d| d["@id"] }.sort end def test_property_parents + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23changeNote" + return unless last_response.ok? # depending if owlapi import SKOS + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23changeNote/parents" assert last_response.ok? pr = MultiJson.load(last_response.body) @@ -191,6 +223,9 @@ def test_property_children ch = MultiJson.load(last_response.body) assert_empty ch + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23semanticRelation" + return unless last_response.ok? # depending if owlapi import SKOS + get "/ontologies/#{@@acronyms.first}/properties/http%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23semanticRelation/children" assert last_response.ok? ch = MultiJson.load(last_response.body) From 721ea063f970452a60ef72dcfdada28a74b0e77f Mon Sep 17 00:00:00 2001 From: = Date: Thu, 5 Feb 2026 23:56:25 -0800 Subject: [PATCH 071/173] fixed the unit test test_show_all_collection to allow for two optional collections: term_search and test_solr --- Gemfile.lock | 2 +- test/controllers/test_search_models_controller.rb | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9b1f42b5c..08eb3c760 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: b731028f1a6781ff2254238486c5b057c39f4596 + revision: c60f8bcad0450456ae3ee2c3a66fe386bba84b56 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index b62c3c09b..9b7ab3a60 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -18,8 +18,11 @@ def test_show_all_collection get '/admin/search/collections' assert last_response.ok? res = MultiJson.load(last_response.body) - array = %w[ontology_data ontology_metadata prop_search_core1 term_search_core1] - assert_equal res["collections"].sort , array.sort + required = %w[ontology_data ontology_metadata prop_search_core1 term_search_core1] + allowed_extra = %w[term_search test_solr] + collections = res["collections"] + assert_empty required - collections + assert_empty collections - (required + allowed_extra) end def test_collection_schema @@ -411,4 +414,4 @@ def test_search_data assert_includes count, res['totalCount'] end -end \ No newline at end of file +end From 30447888039860091492d7f124bee86898a8d767 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 8 Feb 2026 10:42:43 -0800 Subject: [PATCH 072/173] added resource dereference controller and tests --- .../dereference_resource_controller.rb | 53 +++++ lib/rack/content_negotiation.rb | 131 ++++++++++++ lib/rack/downcase_headers.rb | 15 ++ models/simple_wrappers.rb | 2 + .../test_dereference_resource_controller.rb | 195 ++++++++++++++++++ 5 files changed, 396 insertions(+) create mode 100644 controllers/dereference_resource_controller.rb create mode 100644 lib/rack/content_negotiation.rb create mode 100644 lib/rack/downcase_headers.rb create mode 100644 test/controllers/test_dereference_resource_controller.rb diff --git a/controllers/dereference_resource_controller.rb b/controllers/dereference_resource_controller.rb new file mode 100644 index 000000000..8b69efdb5 --- /dev/null +++ b/controllers/dereference_resource_controller.rb @@ -0,0 +1,53 @@ +use Rack::ContentNegotiation + +class DereferenceResourceController < ApplicationController + namespace "/ontologies" do + get "/:acronym/resolve/:uri" do + acronym = params[:acronym] + uri = params[:uri] + + if acronym.blank? || uri.blank? + error 500, "Usage: ontologies/:acronym/resolve/:uri?output_format= OR POST: acronym, uri, output_format parameters" + end + + output_format = env["format"].presence || params[:output_format].presence || 'application/n-triples' + + process_request(acronym, uri, output_format) + end + + private + + def process_request(acronym_param, uri_param, output_format) + acronym = acronym_param + uri = URI.decode_www_form_component(uri_param) + + error 500, "INVALID URI" unless valid_url?(uri) + sub = LinkedData::Models::Ontology.find(acronym).first&.latest_submission + + error 500, "Ontology not found" unless sub + + r = Resource.new(sub.id, uri) + case output_format + when 'application/ld+json', 'application/json' + r.to_json + when 'application/rdf+xml', 'application/xml' + r.to_xml + when 'text/turtle' + r.to_turtle + when 'application/n-triples' + r.to_ntriples + else + error 500, "Invalid output format, valid format are: application/json, application/ld+json, application/xml, application/rdf+xml, text/turtle and application/n-triples" + end + + + end + + def valid_url?(url) + uri = URI.parse(url) + uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS) + rescue URI::InvalidURIError + false + end + end +end \ No newline at end of file diff --git a/lib/rack/content_negotiation.rb b/lib/rack/content_negotiation.rb new file mode 100644 index 000000000..4c91da6af --- /dev/null +++ b/lib/rack/content_negotiation.rb @@ -0,0 +1,131 @@ +module Rack + class ContentNegotiation + DEFAULT_CONTENT_TYPE = "application/n-triples" # N-Triples + VARY = { 'Vary' => 'Accept' }.freeze + ENDPOINTS_FILTER = %r{^/ontologies/[^/]+/resolve/[^/]+$} # Accepted API endpoints to apply content negotiation + + # @return [#call] + attr_reader :app + + # @return [Hash{Symbol => String}] + attr_reader :options + + ## + # @param [#call] app + # @param [Hash{Symbol => Object}] options + # Other options passed to writer. + # @option options [String] :default (DEFAULT_CONTENT_TYPE) Specific content type + # @option options [RDF::Format, #to_sym] :format Specific RDF writer format to use + def initialize(app, options = {}) + @app, @options = app, options + @options[:default] = (@options[:default] || DEFAULT_CONTENT_TYPE).to_s + end + + ## + # Handles a Rack protocol request. + # Parses Accept header to find appropriate mime-type and sets content_type accordingly. + # + # Inserts ordered content types into the environment as `ORDERED_CONTENT_TYPES` if an Accept header is present + # + # @param [Hash{String => String}] env + # @return [Array(Integer, Hash, #each)] Status, Headers and Body + # @see https://rubydoc.info/github/rack/rack/file/SPEC + def call(env) + if env['PATH_INFO'].match?(ENDPOINTS_FILTER) + if env.has_key?('HTTP_ACCEPT') + accepted_types = parse_accept_header(env['HTTP_ACCEPT']) + if !accepted_types.empty? + env["format"] = accepted_types.first + add_content_type_header(app.call(env), env["format"]) + else + not_acceptable + end + else + env["format"] = options[:default] + add_content_type_header(app.call(env), env["format"]) + end + else + app.call(env) + end + end + + protected + + # Parses an HTTP `Accept` header, returning an array of MIME content types ordered by precedence rules. + # + # @param [String, #to_s] header + # @return [Array] Array of content types sorted by precedence + # @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 + def parse_accept_header(header) + entries = header.to_s.split(',') + parsed_entries = entries.map { |entry| parse_accept_entry(entry) } + sorted_entries = parsed_entries.sort_by { |entry| entry.quality }.reverse + content_types = sorted_entries.map { |entry| entry.content_type } + content_types.flatten.compact + end + + + + # Parses an individual entry from the Accept header. + # + # @param [String] entry An entry from the Accept header + # @return [Entry] An object representing the parsed entry + def parse_accept_entry(entry) + # Represents an entry parsed from the Accept header + entry_struct = Struct.new(:content_type, :quality, :wildcard_count, :param_count) + content_type, *params = entry.split(';').map(&:strip) + quality = 1.0 # Default quality + params.reject! do |param| + if param.start_with?('q=') + quality = param[2..-1].to_f + true + end + end + wildcard_count = content_type.count('*') + entry_struct.new(content_type, quality, wildcard_count, params.size) + end + + + ## + # Returns a content type appropriate for the given `media_range`, + # returns `nil` if `media_range` contains a wildcard subtype + # that is not mapped. + # + # @param [String, #to_s] media_range + # @return [String, nil] + def find_content_type_for_media_range(media_range) + case media_range.to_s + when '*/*', 'text/*' + options[:default] + when 'application/n-triples' + 'application/n-triples' + when 'text/turtle' + 'text/turtle' + when 'application/json', 'application/ld+json', 'application/*' + 'application/ld+json' + when 'text/xml', 'text/rdf+xml', 'application/rdf+xml', 'application/xml' + 'application/rdf+xml' + else + nil + end + end + + ## + # Outputs an HTTP `406 Not Acceptable` response. + # + # @param [String, #to_s] message + # @return [Array(Integer, Hash, #each)] + def not_acceptable(message = nil) + code = 406 + http_status = [code, Rack::Utils::HTTP_STATUS_CODES[code]].join(' ') + message = http_status + (message.nil? ? "\n" : " (#{message})\n") + [code, { 'Content-Type' => "text/plain" }.merge(VARY), [message]] + end + + def add_content_type_header(response, type) + response[1] = response[1].merge(VARY).merge('Content-Type' => type) + response + end + + end +end diff --git a/lib/rack/downcase_headers.rb b/lib/rack/downcase_headers.rb new file mode 100644 index 000000000..5aa3ae28d --- /dev/null +++ b/lib/rack/downcase_headers.rb @@ -0,0 +1,15 @@ +module Rack + class DowncaseHeaders + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + downcased_headers = headers.each_with_object({}) do |(key, value), new_headers| + new_headers[key.downcase] = value + end + [status, downcased_headers, body] + end + end +end \ No newline at end of file diff --git a/models/simple_wrappers.rb b/models/simple_wrappers.rb index e4097affd..0d59a5187 100644 --- a/models/simple_wrappers.rb +++ b/models/simple_wrappers.rb @@ -29,3 +29,5 @@ ProvisionalRelation = LinkedData::Models::ProvisionalRelation SearchHelper = Sinatra::Helpers::SearchHelper + +Resource = LinkedData::Models::Resource diff --git a/test/controllers/test_dereference_resource_controller.rb b/test/controllers/test_dereference_resource_controller.rb new file mode 100644 index 000000000..03427c41f --- /dev/null +++ b/test/controllers/test_dereference_resource_controller.rb @@ -0,0 +1,195 @@ +require_relative '../test_case' +require 'rexml/document' + +class TestDereferenceResourceController < TestCase + + def before_suite + LinkedData::SampleData::Ontology.create_ontologies_and_submissions({ + process_submission: true, + process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false}, + acronym: 'INRAETHESDEREF', + name: 'INRAETHES', + file_path: './test/data/ontology_files/thesaurusINRAE_nouv_structure.rdf', + ont_count: 1, + ontology_format: 'SKOS', + submission_count: 1 + }) + + @@graph = "INRAETHESDEREF-0" + @@uri = CGI.escape("http://opendata.inrae.fr/thesaurusINRAE/c_6496") + end + + def test_dereference_resource_controller_json + header 'Accept', 'application/json' + get "/ontologies/#{@@graph}/resolve/#{@@uri}" + assert last_response.ok? + + result = last_response.body + expected_result = <<-JSON + { + "@context": { + "ns0": "http://opendata.inrae.fr/thesaurusINRAE/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "owl": "http://www.w3.org/2002/07/owl#", + "skos": "http://www.w3.org/2004/02/skos/core#" + }, + "@graph": [ + { + "@id": "ns0:c_6496", + "@type": [ + "owl:NamedIndividual", + "skos:Concept" + ], + "skos:broader": { + "@id": "ns0:c_a9d99f3a" + }, + "skos:topConceptOf": { + "@id": "ns0:mt_65" + }, + "skos:inScheme": [ + { + "@id": "ns0:thesaurusINRAE" + }, + { + "@id": "ns0:mt_65" + } + ], + "skos:prefLabel": { + "@value": "altération de l'ADN", + "@language": "fr" + } + }, + { + "@id": "ns0:mt_65", + "skos:hasTopConcept": { + "@id": "ns0:c_6496" + } + } + ] + } + JSON + a = sort_nested_hash(JSON.parse(result)) + b = sort_nested_hash(JSON.parse(expected_result)) + assert_equal b, a + end + + def test_dereference_resource_controller_xml + header 'Accept', 'application/xml' + get "/ontologies/#{@@graph}/resolve/#{@@uri}" + assert last_response.ok? + + result = last_response.body + + expected_result_1 = <<-XML + + + + + + + + + altération de l'ADN + + + + + + XML + + expected_result_2 = <<-XML + + + + + + + altération de l'ADN + + + + + + + + XML + + + clean_xml = -> (x) { x.strip.gsub('/>', '').gsub('', '').split(' ').reject(&:empty?)} + + + a = result.gsub('\\"', '"')[1..-2].split("\\n").map{|x| clean_xml.call(x)}.flatten + b_1 = expected_result_1.split("\n").map{|x| clean_xml.call(x)}.flatten + b_2 = expected_result_2.split("\n").map{|x| clean_xml.call(x)}.flatten + + assert_includes [b_1.sort, b_2.sort], a.sort + end + + def test_dereference_resource_controller_ntriples + header 'Accept', 'application/n-triples' + get "/ontologies/#{@@graph}/resolve/#{@@uri}" + assert last_response.ok? + + result = last_response.body + expected_result = <<-NTRIPLES + . + . + . + . + . + . + "alt\\u00E9rationdel'ADN"@fr . + . + NTRIPLES + a = result.gsub(' ', '').split("\n").reject(&:empty?) + b = expected_result.gsub(' ', '').split("\n").reject(&:empty?) + assert_equal b.sort, a.sort + end + + def test_dereference_resource_controller_turtle + header 'Accept', 'text/turtle' + get "/ontologies/#{@@graph}/resolve/#{@@uri}" + assert last_response.ok? + + result = last_response.body + expected_result = <<-TURTLE + @prefix rdf: . + @prefix ns0: . + @prefix owl: . + @prefix skos: . + + ns0:c_6496 + a owl:NamedIndividual, skos:Concept ; + skos:broader ns0:c_a9d99f3a ; + skos:inScheme ns0:mt_65, ns0:thesaurusINRAE ; + skos:prefLabel "altération de l'ADN"@fr ; + skos:topConceptOf ns0:mt_65 . + + ns0:mt_65 + skos:hasTopConcept ns0:c_6496 . + TURTLE + a = result.gsub(' ', '').split("\n").reject(&:empty?) + b = expected_result.gsub(' ', '').split("\n").reject(&:empty?) + + assert_equal b.sort, a.sort + end + + private + + def sort_nested_hash(hash) + sorted_hash = {} + + hash.each do |key, value| + if value.is_a?(Hash) + sorted_hash[key] = sort_nested_hash(value) + elsif value.is_a?(Array) + sorted_hash[key] = value.map { |item| item.is_a?(Hash) ? sort_nested_hash(item) : item }.sort_by { |item| item.to_s } + else + sorted_hash[key] = value + end + end + + sorted_hash.sort.to_h + end + +end From 651cd58f5e764bde563175c9e279940adfeea9d2 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 11 Feb 2026 12:39:57 -0800 Subject: [PATCH 073/173] moved redis_goo and redis_http to application_helper --- controllers/admin_controller.rb | 10 ---------- helpers/application_helper.rb | 13 +++++++++++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/controllers/admin_controller.rb b/controllers/admin_controller.rb index b16a92a2c..a355329cc 100644 --- a/controllers/admin_controller.rb +++ b/controllers/admin_controller.rb @@ -200,15 +200,5 @@ class AdminController < ApplicationController end end - private - - def redis_goo - Redis.new(host: LinkedData.settings.goo_redis_host, port: LinkedData.settings.goo_redis_port, timeout: 30) - end - - def redis_http - Redis.new(host: LinkedData.settings.http_redis_host, port: LinkedData.settings.http_redis_port, timeout: 30) - end - end end diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb index 64fd7da93..9bcc61cc0 100644 --- a/helpers/application_helper.rb +++ b/helpers/application_helper.rb @@ -550,6 +550,14 @@ def redis Redis.new(host: Annotator.settings.annotator_redis_host, port: Annotator.settings.annotator_redis_port, timeout: 30) end + def redis_goo + Redis.new(host: LinkedData.settings.goo_redis_host, port: LinkedData.settings.goo_redis_port, timeout: 30) + end + + def redis_http + Redis.new(host: LinkedData.settings.http_redis_host, port: LinkedData.settings.http_redis_port, timeout: 30) + end + private def naive_expiring_cache_write(key, object, timeout = 60) @@ -594,6 +602,11 @@ def assign_creator_if_applicable(obj) obj.creator = current_user end + + def update_current_user(user) + Thread.current[:remote_user] = user + env.update("REMOTE_USER" => user) + end end end end From b217034215d326d034e21ce0d975abe3a18863c8 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 11 Feb 2026 12:42:04 -0800 Subject: [PATCH 074/173] Gemfile.lock update --- Gemfile.lock | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 08eb3c760..16d8dc47a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: c60f8bcad0450456ae3ee2c3a66fe386bba84b56 + revision: 3204c0a830d344eb9ae1db82c22b46be1ef468b3 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -185,7 +185,7 @@ GEM ed25519 (1.4.0) et-orbi (1.4.0) tzinfo - faraday (2.14.0) + faraday (2.14.1) faraday-net_http (>= 2.0, < 3.5) json logger @@ -355,8 +355,9 @@ GEM net-protocol net-ssh (7.3.0) netrc (0.11.0) - oj (3.16.14) + oj (3.16.15) bigdecimal (>= 3.0) + ostruct (>= 0.2) omni_logger (0.1.4) logger os (1.1.4) @@ -622,7 +623,7 @@ CHECKSUMS drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc - faraday (2.14.0) sha256=8699cfe5d97e55268f2596f9a9d5a43736808a943714e3d9a53e6110593941cd + faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe @@ -707,7 +708,7 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f - oj (3.16.14) sha256=94da4f737f5c67aa52e2231fe2adb5257c0c95822fe7e3793a07c69542362571 + oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f From f96728a828479299196e6210219a3911b3560672 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 11 Feb 2026 12:43:15 -0800 Subject: [PATCH 075/173] added user OAuth authentication capability --- config/environments/test.rb | 18 +++ controllers/users_controller.rb | 82 ++++++-------- helpers/users_helper.rb | 67 ++++++++++- test/controllers/test_users_controller.rb | 129 +++++++++------------- 4 files changed, 166 insertions(+), 130 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 0080342ad..26b69ebc4 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -46,6 +46,24 @@ config.ontology_analytics_redis_host = REDIS_PERSISTENT_HOST.to_s config.ontology_analytics_redis_port = REDIS_PORT.to_i config.ontology_analytics_redis_field = 'test_analytics' + config.oauth_providers = { + github: { + check: :access_token, + link: 'https://api.github.com/user' + }, + keycloak: { + check: :jwt_token, + cert: 'KEYCLOAK_SECRET_KEY' + }, + orcid: { + check: :access_token, + link: 'https://pub.orcid.org/v3.0/me' + }, + google: { + check: :access_token, + link: 'https://www.googleapis.com/oauth2/v3/userinfo' + } + } end Annotator.config do |config| diff --git a/controllers/users_controller.rb b/controllers/users_controller.rb index 41fc155ca..4e4f4db25 100644 --- a/controllers/users_controller.rb +++ b/controllers/users_controller.rb @@ -1,15 +1,22 @@ + class UsersController < ApplicationController namespace "/users" do - post "/authenticate" do - user_id = params["user"] - user_password = params["password"] + # Modify params to show all user attributes params["display"] = User.attributes.join(",") - user = User.find(user_id).include(User.goo_attrs_to_load(includes_param) + [:passwordHash]).first - authenticated = user.authenticate(user_password) unless user.nil? - error 401, "Username/password combination invalid" unless authenticated - user.show_apikey = true + + if params["access_token"] + user = oauth_authenticate(params) + user.bring(*User.goo_attrs_to_load(includes_param)) + else + user = login_password_authenticate(params) + end + unless user.nil? + user.update_last_login + user.show_apikey = true + update_current_user(user) + end reply user end @@ -19,20 +26,15 @@ class UsersController < ApplicationController # to click and login to the UI. The token can then be provided to # the /reset_password endpoint to actually reset the password. post "/create_reset_password_token" do - email = params["email"] + email = params["email"] username = params["username"] - user = LinkedData::Models::User.where(email: email, username: username).include(LinkedData::Models::User.attributes).first - error 404, "User not found" unless user - reset_token = token(36) - user.resetToken = reset_token - user.resetTokenExpireTime = Time.now.to_i + 1.hours.to_i + user = send_reset_token(email, username) + if user.valid? - user.save(override_security: true) - LinkedData::Utils::Notifications.reset_password(user, reset_token) + halt 204 else error 422, user.errors end - halt 204 end ## @@ -41,31 +43,15 @@ class UsersController < ApplicationController # can be used to log a user in. This will allow them to change their # password and update the user object. post "/reset_password" do - email = params["email"] || "" - username = params["username"] || "" - token = params["token"] || "" + email = params["email"] || "" + username = params["username"] || "" + token = params["token"] || "" params["display"] = User.attributes.join(",") # used to serialize everything via the serializer - user = LinkedData::Models::User.where(email: email, username: username).include(User.goo_attrs_to_load(includes_param)).first - error 404, "User not found" unless user - - user.bring(:resetToken) - user.bring(:resetTokenExpireTime) - user.bring(:passwordHash) - - if token.eql?(user.resetToken) - error 401, "Invalid password reset token" if user.resetTokenExpireTime.nil? - error 401, "The password reset token expired" if user.resetTokenExpireTime < Time.now.to_i - user.resetToken = nil - user.resetTokenExpireTime = nil - - if user.valid? - user.save(override_security: true) - user.show_apikey = true - reply user - else - error 422, "Error resetting password" - end + + user, token_accepted = reset_password(email, username, token) + if token_accepted + reply user else error 401, "Password reset not authorized with this token" end @@ -86,6 +72,14 @@ class UsersController < ApplicationController reply user end + # Display a single user + get '/:username/ontologies' do + user = User.find(params[:username]).first + error 404, "Cannot find user with username `#{params['username']}`" if user.nil? + check_last_modified(user) + reply user.createdOntologies + end + # Create user post do create_user @@ -118,21 +112,15 @@ class UsersController < ApplicationController private - def token(len) - chars = ("a".."z").to_a + ("A".."Z").to_a + ("1".."9").to_a - token = "" - 1.upto(len) { |i| token << chars[rand(chars.size-1)] } - token - end - def create_user + def create_user(send_notifications: true) params ||= @params user = User.find(params["username"]).first error 409, "User with username `#{params["username"]}` already exists" unless user.nil? params.delete("role") unless current_user.admin? user = instance_from_params(User, params) if user.valid? - user.save + user.save(send_notifications: send_notifications) else error 422, user.errors end diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index 22cce9e28..0669b8f87 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -19,18 +19,75 @@ def get_users def filter_for_user_onts(obj) return obj unless obj.is_a?(Enumerable) - return obj unless env['REMOTE_USER'] - return obj if env['REMOTE_USER'].customOntology.empty? - return obj if params['ignore_custom_ontologies'] + return obj unless env["REMOTE_USER"] + return obj if env["REMOTE_USER"].customOntology.empty? + return obj if params["ignore_custom_ontologies"] - user = env['REMOTE_USER'] + user = env["REMOTE_USER"] if obj.first.is_a?(LinkedData::Models::Ontology) - obj = obj.select { |o| user.custom_ontology_id_set.include?(o.id.to_s) } + obj = obj.select {|o| user.custom_ontology_id_set.include?(o.id.to_s)} end obj end + + def send_reset_token(email, username) + user = LinkedData::Models::User.where(email: email, username: username).include(LinkedData::Models::User.attributes).first + error 404, "User not found" unless user + reset_token = token(36) + user.resetToken = reset_token + user.resetTokenExpireTime = Time.now.to_i + 1.hours.to_i + + user.save(override_security: true) + LinkedData::Utils::Notifications.reset_password(user, reset_token) + user + end + + def token(len) + chars = ("a".."z").to_a + ("A".."Z").to_a + ("1".."9").to_a + token = "" + 1.upto(len) { |i| token << chars[rand(chars.size-1)] } + token + end + + def reset_password(email, username, token) + user = LinkedData::Models::User.where(email: email, username: username).include(User.goo_attrs_to_load(includes_param) + [:resetToken, :passwordHash, :resetTokenExpireTime]).first + + error 404, "User not found" unless user + + user.show_apikey = true + token_accepted = token.eql?(user.resetToken) + if token_accepted + error 401, "Invalid password reset token" if user.resetTokenExpireTime.nil? + error 401, "The password reset token expired" if user.resetTokenExpireTime < Time.now.to_i + user.resetToken = nil + user.resetTokenExpireTime = nil + user.save(override_security: true) if user.valid? + user.show_apikey = true + end + + [user, token_accepted] + end + + def oauth_authenticate(params) + access_token = params["access_token"] + provider = params["token_provider"] + user = LinkedData::Models::User.oauth_authenticate(access_token, provider) + error 401, "Access token invalid"if user.nil? + user + end + + def login_password_authenticate(params) + user_id = params["user"] + user_password = params["password"] + user = User.find(user_id).include(User.goo_attrs_to_load(includes_param) + [:passwordHash]).first + authenticated = false + authenticated = user.authenticate(user_password) unless user.nil? + error 401, "Username/password combination invalid" unless authenticated + + user + end end end end diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb index 223cd641b..47c929c33 100644 --- a/test/controllers/test_users_controller.rb +++ b/test/controllers/test_users_controller.rb @@ -21,48 +21,6 @@ def self._delete_users end end - def test_rejects_restricted_user_attributes_on_post_and_patch - username = "restricted_test_user" - email = "restricted@example.org" - password = "testpass" - - # Create baseline user - post "/users", { - username: username, - email: email, - password: password - } - assert_equal 201, last_response.status - - # POST attempt with restricted attributes - post "/users", { - username: "new-user", - email: "new@example.org", - password: "newpass", - created: DateTime.now + 1.year, - resetToken: "invalid", - resetTokenExpireTime: DateTime.now - } - assert_equal 201, last_response.status - user = User.find('new-user').include(User.attributes).first - assert_nil user.resetToken - assert_nil user.resetTokenExpireTime - assert_operator Time.now.to_time.to_i, :>=, user.created.to_time.to_i - - # PATCH attempt with restricted attributes - patch "/users/#{username}", { - created: DateTime.now + 1.year, - resetToken: "still-invalid", - resetTokenExpireTime: DateTime.now - } - assert_equal 204, last_response.status - user = User.find('new-user').include(User.attributes).first - assert_nil user.resetToken - assert_nil user.resetTokenExpireTime - assert_operator Time.at(Time.now.to_i), :>=, user.created.to_time - - end - def test_admin_creation existent_user = @@users.first #no admin @@ -80,18 +38,6 @@ def test_all_users users = MultiJson.load(last_response.body) assert users.any? {|u| u["username"].eql?("fred")} assert users.length >= @@usernames.length - - get '/users?search=fred' - assert last_response.ok? - users = MultiJson.load(last_response.body) - assert users.all? {|u| u["username"].include?("fred")} - assert users.length == 1 - - get '/users?page=1&pagesize=5' - assert last_response.ok? - users = MultiJson.load(last_response.body) - assert_equal 5, users["collection"].length - assert users["totalCount"] >= @@usernames.length end def test_single_user @@ -102,21 +48,6 @@ def test_single_user assert_equal "fred", MultiJson.load(last_response.body)["username"] end - def test_hide_sensitive_data - user = @@users[0] - reset_token = token(36) - user.resetToken = reset_token - user.resetTokenExpireTime = Time.now.to_i - 2.hours.to_i - user.save - - username = user.username - get "/users/#{username}?display=resetToken,resetTokenExpireTime" - assert last_response.ok? - - refute_includes MultiJson.load(last_response.body), 'resetToken', "resetToken should NOT be included in the response" - refute_includes MultiJson.load(last_response.body), 'resetTokenExpireTime', "resetTokenExpireTime should NOT be included in the response" - end - def test_create_new_user user = {email: "#{@@username}@example.org", password: "pass_the_word"} put "/users/#{@@username}", MultiJson.dump(user), "CONTENT_TYPE" => "application/json" @@ -136,7 +67,7 @@ def test_create_new_user get "/users/#{@@username}" assert last_response.ok? - assert MultiJson.load(last_response.body)["username"].eql?(@@username) + assert MultiJson.load(last_response.body)["username"].eql?(@@username) assert_equal "test_user@example.org", MultiJson.load(last_response.body)["email"] end @@ -187,7 +118,6 @@ def test_reset_password_expired_token assert_equal 401, last_response.status end - def test_create_new_invalid_user put "/users/totally_new_user" assert last_response.status == 422 @@ -238,18 +168,61 @@ def test_authentication assert user["username"].eql?(@@usernames.first) end - private + def test_oauth_authentication + fake_responses = { + github: { + id: 123456789, + login: 'github_user', + email: 'github_user@example.com', + name: 'GitHub User', + avatar_url: 'https://avatars.githubusercontent.com/u/123456789' + }, + google: { + sub: 'google_user_id', + email: 'google_user@example.com', + name: 'Google User', + given_name: 'Google', + family_name: 'User', + picture: 'https://lh3.googleusercontent.com/a-/user-profile-image-url' + }, + orcid: { + orcid: '0000-0002-1825-0097', + email: 'orcid_user@example.com', + name: { + "family-name": 'ORCID', + "given-names": 'User' + } + } + } + + fake_responses.each do |provider, data| + WebMock.stub_request(:get, LinkedData::Models::User.oauth_providers[provider][:link]) + .to_return(status: 200, body: data.to_json, headers: { 'Content-Type' => 'application/json' }) + post "/users/authenticate", {access_token:'jkooko', token_provider: provider.to_s} + assert last_response.ok? + user = MultiJson.load(last_response.body) + assert data[:email], user["email"] + end + end - def token(len) - chars = ("a".."z").to_a + ("A".."Z").to_a + ("1".."9").to_a - token = "" - 1.upto(len) { |i| token << chars[rand(chars.size-1)] } - token + def test_hide_sensitive_data + user = @@users[0] + reset_token = "reset_password_token" + user.resetToken = reset_token + user.save + username = user.username + get "/users/#{username}?display=resetToken,passwordHash" + assert last_response.ok? + refute_includes MultiJson.load(last_response.body), 'resetToken', "resetToken should NOT be included in the response" + refute_includes MultiJson.load(last_response.body), 'passwordHash', "passwordHash should NOT be included in the response" end + private + def _delete_user(username) LinkedData::Models::User.find(@@username).first&.delete end + def _create_admin_user(apikey: nil) user = {email: "#{@@username}@example.org", password: "pass_the_word", role: ['ADMINISTRATOR']} _delete_user(@@username) @@ -276,4 +249,4 @@ def _create_admin_user(apikey: nil) true if user["role"].eql?(['ADMINISTRATOR']) end -end +end \ No newline at end of file From ca1d1a89aa2bb25afdcb55e1d0420421a8fdd117 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 24 Feb 2026 18:26:27 -0800 Subject: [PATCH 076/173] use ruby 3.2.9 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index be94e6f53..e650c01d9 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.2.9 From 175b077cd163db421a3fe00e04092db1669ce7fd Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 24 Feb 2026 20:54:29 -0800 Subject: [PATCH 077/173] prune platforms --- Gemfile.lock | 206 +-------------------------------------------------- 1 file changed, 1 insertion(+), 205 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 16d8dc47a..02c852a12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -515,20 +515,11 @@ GEM webrick (1.9.2) PLATFORMS - aarch64-linux aarch64-linux-gnu - aarch64-linux-musl - arm-linux-gnu - arm-linux-musl arm64-darwin ruby - x86-linux - x86-linux-gnu - x86-linux-musl x86_64-darwin - x86_64-linux x86_64-linux-gnu - x86_64-linux-musl DEPENDENCIES activesupport @@ -592,200 +583,5 @@ DEPENDENCIES webmock webrick -CHECKSUMS - activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae - addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 - airbrussh (1.6.0) sha256=7e2cf581f2319d2c2b2b672c9fc486efb4dfcfed4bd2dadbef5f10b8b2a000d0 - ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 - ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 - base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b - bcp47_spec (0.2.1) sha256=3fd62edf96c126bd9624e4319ac74082a966081859d1ee0ef3c3041640a37810 - bcrypt (3.1.21) sha256=5964613d750a42c7ee5dc61f7b9336fb6caca429ba4ac9f2011609946e4a2dcf - bcrypt_pbkdf (1.1.2) sha256=c2414c23ce66869b3eb9f643d6a3374d8322dfb5078125c82792304c10b94cf6 - bcrypt_pbkdf (1.1.2-arm64-darwin) sha256=afdd6feb6ed5a97b8e44caacb3f2d641b98af78e6a516d4a3520b69af5cf9fea - bcrypt_pbkdf (1.1.2-x86_64-darwin) sha256=35f5639d0058e6c2cc2f856f9c0b14080543268d3047abe6bc81c513093caa0e - bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 - builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f - byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e - capistrano (3.20.0) sha256=0113e58dda99add0342e56a244f664734c59f442c5ed734f5303b0b559b479c9 - capistrano-bundler (2.2.0) sha256=47b4cf2ea17ea132bb0a5cabc5663443f5190a54f4da5b322d04e1558ff1468c - capistrano-locally (0.3.0) sha256=ad44252f19641e8dd980f7cb0241e9ac11919b1f4cbdb642d272a6d0edcb84eb - capistrano-rbenv (2.2.0) sha256=3c8f39b7c624f3806630dcb475484bb3579aef07a40efe85089d83f64b0c35f5 - coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b - concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab - connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a - crack (0.4.5) sha256=798416fb29b8c9f655d139d5559169b39c4a0a3b8f8f39b7f670eec1af9b21b3 - dante (0.2.0) sha256=939776f04b4d253ffbbcf53341631aa2ee6e6cf314dedade2e60ac43b40a6fe6 - date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 - docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e - domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - down (5.4.2) sha256=516e5e01e7a96214a7e2cd155aac6f700593038ae6c857c0f4a05413b1c58acf - drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 - ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 - et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc - faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c - faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad - faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c - faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe - ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c - ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 - ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 - ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 - ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 - ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f - ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 - ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 - ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 - ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f - ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 - fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 - gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 - get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba - goo (0.0.2) - google-analytics-data (0.7.2) sha256=5e4bf6dc575c7725c2b32541725749890a88e0a64ff0ad7e8a73f75ad5a1bbc9 - google-analytics-data-v1beta (0.17.0) sha256=1145d30d794bcf6bf8b723140a0ee2c445e740b82cf4051a31d992e7393168a6 - google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf - google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7 - google-cloud-errors (1.5.0) sha256=b56be28b8c10628125214dde571b925cfcebdbc58619e598250c37a2114f7b4b - google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b - google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 - google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 - google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c - google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 - google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 - google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 - googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe - googleapis-common-protos-types (1.20.0) sha256=5e374b06bcfc7e13556e7c0d87b99f1fa3d42de6396a1de3d8fc13aefb4dd07f - googleauth (1.16.1) sha256=36776bce9d55d8c1a0c6638c939b000dcee5954ca5b728f06ec4c2df4a46709c - grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb - grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 - grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 - grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 - grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 - grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be - haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c - hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 - htmlentities (4.4.2) sha256=bbafbdf69f2eca9262be4efef7e43e6a1de54c95eb600f26984f71d2fe96c5c3 - http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 - http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 - i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 - io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986 - json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef - json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc - json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 - jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 - kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 - language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc - libxml-ruby (5.0.5) sha256=f1bc07152982df555d70159a694ee2a53539de2cdad4b3c8a447fbb15e7e4e9a - link_header (0.0.8) sha256=15c65ce43b29f739b30d05e5f25c22c23797e89cf6f905dbb595fb4c70cb55f9 - lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 - logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 - macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 - mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 - method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 - mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0203) sha256=54353d693af028847391c28361c07d4b8b689cad78c3e1cc272fb1205c6d2a2f - mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef - minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb - minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 - minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c - minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 - mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 - multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 - mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22 - ncbo_annotator (0.0.1) - ncbo_cron (0.0.1) - ncbo_ontology_recommender (0.0.1) - net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 - net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 - net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 - net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6 - net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 - net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 - net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d - net-sftp (4.0.0) sha256=65bb91c859c2f93b09826757af11b69af931a3a9155050f50d1b06d384526364 - net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 - net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 - netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f - oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd - omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e - ontologies_linked_data (0.0.1) - os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f - ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 - pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 - parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 - parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 - parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 - pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 - prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 - pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e - public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 - raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 - racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f - rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 - rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 - rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2 - rack-cache (1.17.0) sha256=49592f3ef2173b0f5524df98bb801fb411e839869e7ce84ac428dc492bf0eb90 - rack-contrib (2.5.0) sha256=51bd2ce82b8a3270f9173130c4cdaea72aab8b03dce8cd6af1c4344d84a32d02 - rack-cors (3.0.0) sha256=7b95be61db39606906b61b83bd7203fa802b0ceaaad8fcb2fef39e097bf53f68 - rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78 - rack-post-body-to-params (0.1.8) - rack-protection (4.2.1) - rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 - rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 - rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 - rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 - rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a - raindrops (0.20.1) sha256=aa0eb9ff6834f2d9e232ba688bd49cb30be893bc5a3452e74722c94c1fab4730 - rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c - rdf (3.3.1) sha256=dda6a2c95198915fc63d66ee270e35d4a76d431720747a2cf97ecd92062fa150 - rdf-raptor (3.3.0) - rdf-rdfxml (3.3.0) sha256=11647f6111b97b6a9b82413bd9810d4bb5524aa7dd06b3c1330bf58ec3aa6a9a - rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b - rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 - redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae - redis-client (0.26.4) sha256=3ad70beff5da2653e02dfeae996e7d8d7147a558da12b16b2282ad345e4c7120 - redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 - redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 - regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 - reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 - request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb - rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 - rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 - rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b - rubocop (1.84.1) sha256=14cc626f355141f5a2ef53c10a68d66b13bb30639b26370a76559096cc6bcc1a - rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd - ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 - ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 - ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef - rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c - rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 - securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 - shotgun (0.9) - signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b - simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 - simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5 - simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 - simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 - sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080 - sinatra-contrib (4.2.1) - sparql-client (3.2.2) - sshkit (1.25.0) sha256=c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744 - systemu (2.6.5) sha256=01f7d014b1453b28e5781e15c4d7d63fc9221c29b174b7aae5253207a75ab33e - temple (0.10.4) sha256=b7a1e94b6f09038ab0b6e4fe0126996055da2c38bec53a8a336f075748fff72c - tilt (2.7.0) sha256=0d5b9ba69f6a36490c64b0eee9f6e9aad517e20dcc848800a06eb116f08c6ab3 - time (0.4.2) sha256=f324e498c3bde9471d45a7d18f874c27980e9867aa5cfca61bebf52262bc3dab - timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af - tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b - unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 - unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f - unicorn (6.1.0) sha256=45dd987add4c2b084c1880a68373af42797a704ad7441faff9b14b4982aa0fc0 - unicorn-worker-killer (0.4.5) sha256=fc3c5dae71566c9e2a165dfbf75664f7bc16fec20251a1d09c3375ffe58b3991 - uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 - uuid (2.3.9) sha256=aec0cf592053cd6e07c13c1ef94c440aba705f22eb1ee767b39631f2760124d7 - webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 - webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 - BUNDLED WITH - 4.0.5 + 2.7.2 From 748eb4c6d5e9d40971b63cf17549525d6b2842a2 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 24 Feb 2026 21:57:52 -0800 Subject: [PATCH 078/173] re-enable capistrano/rbenv --- Capfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Capfile b/Capfile index 95799ba1b..c01b1e450 100644 --- a/Capfile +++ b/Capfile @@ -16,7 +16,7 @@ install_plugin Capistrano::SCM::Git # https://github.com/capistrano/rails # # require 'capistrano/rvm' -# require 'capistrano/rbenv' +require 'capistrano/rbenv' # require 'capistrano/chruby' require 'capistrano/bundler' # require 'capistrano/rails/assets' From 5e9cd8dd520f4c7dbd0e0289ffec02fb1a5255dd Mon Sep 17 00:00:00 2001 From: = Date: Thu, 26 Feb 2026 14:16:07 -0800 Subject: [PATCH 079/173] Gemfile.lock update --- Gemfile.lock | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 16d8dc47a..b2b1eb330 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: e4be8480530700a6a1bd165b03cc6a331a029077 + revision: e86ece03c2d80604cdea4d96bd1de6899f6b4762 branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -29,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 84b63df9694801667f845677a131ced48b92e640 + revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -47,7 +47,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 2ef0e6f86e634d06a20ebb3d12b4160470eface1 + revision: 911f88f75814618f2c39d602c56d9f57245f46da branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 3204c0a830d344eb9ae1db82c22b46be1ef468b3 + revision: 637fdfcfc0f9201a631b4d827d34aa8993325565 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -95,14 +95,6 @@ GIT rack-post-body-to-params (0.1.8) activesupport (>= 2.3) -GIT - remote: https://github.com/palexander/shotgun.git - revision: db198224aaab2e4cb9b049adccb30e387d88bc3b - branch: ncbo - specs: - shotgun (0.9) - rack (>= 1.0) - GIT remote: https://github.com/ruby-rdf/rdf-raptor.git revision: 6392ceabf71c3233b0f7f0172f662bd4a22cd534 @@ -247,7 +239,7 @@ GEM grpc (~> 1.41) googleapis-common-protos-types (1.20.0) google-protobuf (>= 3.18, < 5.a) - googleauth (1.16.1) + googleauth (1.16.2) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.2) google-logging-utils (~> 0.1) @@ -312,13 +304,16 @@ GEM net-imap net-pop net-smtp + mcp (0.7.1) + json-schema (>= 4.1) method_source (1.1.0) mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0203) + mime-types-data (3.2026.0224) mini_mime (1.1.5) - minitest (6.0.1) + minitest (6.0.2) + drb (~> 2.0) prism (~> 1.5) minitest-hooks (1.5.3) minitest (> 5.3) @@ -340,7 +335,7 @@ GEM uri (>= 0.11.1) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - net-imap (0.6.2) + net-imap (0.6.3) date net-protocol net-pop (0.1.2) @@ -365,7 +360,7 @@ GEM pandoc-ruby (2.1.10) parallel (1.27.0) parseconfig (1.1.2) - parser (3.3.10.1) + parser (3.3.10.2) ast (~> 2.4.1) racc pony (1.13.1) @@ -378,7 +373,7 @@ GEM public_suffix (7.0.2) raabro (1.4.0) racc (1.8.1) - rack (3.2.4) + rack (3.2.5) rack-accept (0.4.5) rack (>= 0.4) rack-attack (6.8.0) @@ -439,10 +434,11 @@ GEM rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) - rubocop (1.84.1) + rubocop (1.85.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) + mcp (~> 0.6) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) @@ -581,7 +577,6 @@ DEPENDENCIES request_store rexml rubocop - shotgun! simplecov simplecov-cobertura sinatra @@ -656,7 +651,7 @@ CHECKSUMS google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe googleapis-common-protos-types (1.20.0) sha256=5e374b06bcfc7e13556e7c0d87b99f1fa3d42de6396a1de3d8fc13aefb4dd07f - googleauth (1.16.1) sha256=36776bce9d55d8c1a0c6638c939b000dcee5954ca5b728f06ec4c2df4a46709c + googleauth (1.16.2) sha256=15009502e2e38af71948cda918f230e27d327f6882a1e47967a5a4664930a638 grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 @@ -683,11 +678,12 @@ CHECKSUMS logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 + mcp (0.7.1) sha256=fa967895d6952bad0d981ea907731d8528d2c246d2079d56a9c8bae83d14f1c7 method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0203) sha256=54353d693af028847391c28361c07d4b8b689cad78c3e1cc272fb1205c6d2a2f + mime-types-data (3.2026.0224) sha256=bea02e0168b37f6935696c4fcfeb3374a0a62e82e6187af5f3f3b709bf67e5fd mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef - minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb + minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 @@ -700,7 +696,7 @@ CHECKSUMS net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 - net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6 + net-imap (0.6.3) sha256=9bab75f876596d09ee7bf911a291da478e0cd6badc54dfb82874855ccc82f2ad net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d @@ -716,14 +712,14 @@ CHECKSUMS pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 - parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 + parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357 pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f - rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 + rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3 rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2 rack-cache (1.17.0) sha256=49592f3ef2173b0f5524df98bb801fb411e839869e7ce84ac428dc492bf0eb90 @@ -754,7 +750,7 @@ CHECKSUMS rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b - rubocop (1.84.1) sha256=14cc626f355141f5a2ef53c10a68d66b13bb30639b26370a76559096cc6bcc1a + rubocop (1.85.0) sha256=317407feb681a07d54f64d2f9e1d6b6af1ce7678e51cd658e3ad8bd66da48c01 rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 @@ -762,7 +758,6 @@ CHECKSUMS rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 - shotgun (0.9) signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5 From decafc6a77a2860a4a15857240361d6c5f8bd4cc Mon Sep 17 00:00:00 2001 From: = Date: Thu, 26 Feb 2026 14:17:18 -0800 Subject: [PATCH 080/173] removed the use of shotgun server. Now use: bundle exec rackup -E development -p 9393 --- Gemfile | 2 -- app.rb | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index daf59ce67..bdca47b07 100644 --- a/Gemfile +++ b/Gemfile @@ -58,8 +58,6 @@ gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branc gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' group :development do - # bcrypt_pbkdf and ed35519 is required for capistrano deployments when using ed25519 keys; see https://github.com/miloserdow/capistrano-deploy/issues/42 - gem 'shotgun', github: 'palexander/shotgun', branch: 'ncbo' gem 'rubocop' end diff --git a/app.rb b/app.rb index 08ed31a42..975fe5b64 100644 --- a/app.rb +++ b/app.rb @@ -82,6 +82,9 @@ # Development-specific options if [:development, :console].include?(settings.environment) require 'pry' # Debug by placing 'binding.pry' where you want the interactive console to start + require 'sinatra/reloader' + register Sinatra::Reloader + also_reload './{config,controllers,helpers,models,lib}/**/*.rb' # Show exceptions set :raise_errors, true set :dump_errors, false From 223cae3293ebd895767ed6abef00c60d791071d5 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Feb 2026 10:32:41 -0800 Subject: [PATCH 081/173] fixed routes for Sinatra 4, which changed from objects to arrays --- controllers/home_controller.rb | 51 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/controllers/home_controller.rb b/controllers/home_controller.rb index 654b50e02..e9140d6dd 100644 --- a/controllers/home_controller.rb +++ b/controllers/home_controller.rb @@ -17,7 +17,9 @@ class HomeController < ApplicationController routes.each do |route| next if route.length < 3 || route.split("/").length > 2 route_no_slash = route.gsub("/", "") - context[route_no_slash] = route_to_class_map[route].type_uri.to_s if route_to_class_map[route] && route_to_class_map[route].respond_to?(:type_uri) + mapped_class = route_to_class_map[route] + mapped_type_uri = safe_type_uri(mapped_class) + context[route_no_slash] = mapped_type_uri.to_s unless mapped_type_uri.nil? routes_hash[route_no_slash] = LinkedData.settings.rest_url_prefix+route_no_slash end routes_hash["@context"] = context @@ -131,7 +133,7 @@ def metadata_all cls_info = { attributes: attributes_info, - uri: cls.type_uri, + uri: safe_type_uri(cls), cls: cls } @@ -160,8 +162,10 @@ def routes_by_class routes_by_file = {} all_routes.each do |method, routes| routes.each do |route| - routes_by_file[route.file] ||= [] - routes_by_file[route.file] << route + route_info = parse_route(method, route) + next if route_info[:file].nil? + routes_by_file[route_info[:file]] ||= [] + routes_by_file[route_info[:file]] << route_info end end routes_by_class = {} @@ -187,9 +191,9 @@ def routes_by_class next if cls.nil? routes.each do |route| - next if route.verb == "HEAD" + next if route[:verb] == "HEAD" routes_by_class[cls] ||= [] - routes_by_class[cls] << [route.verb, route.path] + routes_by_class[cls] << [route[:verb], route[:path]] end end @routes_by_class = routes_by_class @@ -210,17 +214,36 @@ def route_to_class_map def routes_list return @navigable_routes if @navigable_routes - routes = Sinatra::Application.routes["GET"] - navigable_routes = [] - Sinatra::Application.each_route do |route| - if route.verb.eql?("GET") - navigable_routes << route.path.split("?").first - end - end + all_routes = Sinatra::Application.routes + get_routes = all_routes["GET"] || all_routes[:GET] || [] + navigable_routes = get_routes.map { |route| parse_route("GET", route)[:path] }.uniq @navigable_routes = navigable_routes navigable_routes end + # Sinatra < 4 routes were objects; Sinatra 4 routes are arrays. + # Normalize both to a common hash used by this controller. + def parse_route(method, route) + if route.respond_to?(:path) && route.respond_to?(:file) + return { verb: route.verb.to_s, path: route.path.to_s.split("?").first, file: route.file } + end + + if route.is_a?(Array) + pattern = route[0] + route_block = route[-1] + file = route_block.respond_to?(:source_location) ? route_block.source_location&.first : nil + return { verb: method.to_s, path: pattern.to_s.split("?").first, file: file } + end + + { verb: method.to_s, path: "", file: nil } + end + + def safe_type_uri(cls) + return nil if cls.nil? || !cls.respond_to?(:type_uri) + cls.type_uri + rescue NoMethodError + nil + end + end end - From 2209513e8eddff46ed8557a5ae78b4f92b7c8546 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 27 Feb 2026 13:54:56 -0800 Subject: [PATCH 082/173] added home controller tests to validate the routes --- test/controllers/test_home_controller.rb | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/controllers/test_home_controller.rb diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb new file mode 100644 index 000000000..1bade976c --- /dev/null +++ b/test/controllers/test_home_controller.rb @@ -0,0 +1,46 @@ +require_relative '../test_case' + +class TestHomeController < TestCase + def test_home_index_returns_links_hash + get '/' + assert last_response.ok?, get_errors(last_response) + + body = MultiJson.load(last_response.body) + assert body.key?('links') + assert_kind_of Hash, body['links'] + end + + def test_home_index_handles_type_uri_failures + bad_class = Class.new do + def self.type_uri + raise NoMethodError, 'model settings missing' + end + end + + klass = Sinatra::Application + original_routes_list = klass.instance_method(:routes_list) rescue nil + original_route_to_class_map = klass.instance_method(:route_to_class_map) rescue nil + + klass.class_eval do + define_method(:routes_list) { ['/broken'] } + define_method(:route_to_class_map) { { '/broken' => bad_class } } + end + + get '/' + assert last_response.ok?, get_errors(last_response) + ensure + klass.class_eval do + if original_routes_list + define_method(:routes_list, original_routes_list) + else + remove_method(:routes_list) rescue nil + end + + if original_route_to_class_map + define_method(:route_to_class_map, original_route_to_class_map) + else + remove_method(:route_to_class_map) rescue nil + end + end + end +end From 0b365285aac6f4b994a008bd01032e689bd63ac5 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 27 Feb 2026 16:27:40 -0800 Subject: [PATCH 083/173] update ncbo_cron gem --- Gemfile | 5 +---- Gemfile.lock | 58 +++++++++++++--------------------------------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/Gemfile b/Gemfile index bdca47b07..922951679 100644 --- a/Gemfile +++ b/Gemfile @@ -12,10 +12,7 @@ gem 'rake' gem 'rexml' # Investigate why unicorn fails to start under ruby 3 without adding rexml gem to the Gemfile gem 'rackup' gem 'sinatra' - -github 'sinatra/sinatra' do - gem 'sinatra-contrib' -end +gem 'sinatra-contrib' gem 'request_store' gem 'parallel' diff --git a/Gemfile.lock b/Gemfile.lock index cb158cd79..59cab63a4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,21 +104,6 @@ GIT ffi (~> 1.15) rdf (~> 3.3) -GIT - remote: https://github.com/sinatra/sinatra.git - revision: 9e5c4ec8ade92c7375f44acf4c6e1103d32d6c12 - specs: - rack-protection (4.2.1) - base64 (>= 0.1.0) - logger (>= 1.6.0) - rack (>= 3.0.0, < 4) - sinatra-contrib (4.2.1) - multi_json (>= 0.0.2) - mustermann (~> 3.0) - rack-protection (= 4.2.1) - sinatra (= 4.2.1) - tilt (~> 2.0) - GEM remote: https://rubygems.org/ specs: @@ -189,15 +174,9 @@ GEM faraday (~> 2.0) ffi (1.17.3) ffi (1.17.3-aarch64-linux-gnu) - ffi (1.17.3-aarch64-linux-musl) - ffi (1.17.3-arm-linux-gnu) - ffi (1.17.3-arm-linux-musl) ffi (1.17.3-arm64-darwin) - ffi (1.17.3-x86-linux-gnu) - ffi (1.17.3-x86-linux-musl) ffi (1.17.3-x86_64-darwin) ffi (1.17.3-x86_64-linux-gnu) - ffi (1.17.3-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -230,7 +209,6 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) - google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -256,9 +234,6 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.70.1-x86-linux) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -387,6 +362,10 @@ GEM rack (>= 3.0.14) rack-mini-profiler (4.0.1) rack (>= 1.2.0) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) rack-session (2.1.1) base64 (>= 0.1.0) rack (>= 3.0.0) @@ -477,6 +456,12 @@ GEM rack-protection (= 4.2.1) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) + sinatra-contrib (4.2.1) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.2.1) + sinatra (= 4.2.1) + tilt (~> 2.0) sshkit (1.25.0) base64 logger @@ -513,18 +498,11 @@ GEM PLATFORMS aarch64-linux aarch64-linux-gnu - aarch64-linux-musl - arm-linux-gnu - arm-linux-musl arm64-darwin ruby - x86-linux - x86-linux-gnu - x86-linux-musl x86_64-darwin x86_64-linux x86_64-linux-gnu - x86_64-linux-musl DEPENDENCIES activesupport @@ -580,7 +558,7 @@ DEPENDENCIES simplecov simplecov-cobertura sinatra - sinatra-contrib! + sinatra-contrib sparql-client! unicorn unicorn-worker-killer @@ -624,15 +602,9 @@ CHECKSUMS faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 - ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 - ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 - ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f - ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 - ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f - ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -646,7 +618,6 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c - google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -655,7 +626,6 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 - grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -727,7 +697,7 @@ CHECKSUMS rack-cors (3.0.0) sha256=7b95be61db39606906b61b83bd7203fa802b0ceaaad8fcb2fef39e097bf53f68 rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78 rack-post-body-to-params (0.1.8) - rack-protection (4.2.1) + rack-protection (4.2.1) sha256=cf6e2842df8c55f5e4d1a4be015e603e19e9bc3a7178bae58949ccbb58558bac rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 @@ -764,7 +734,7 @@ CHECKSUMS simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080 - sinatra-contrib (4.2.1) + sinatra-contrib (4.2.1) sha256=10d091c944d268aa910c618ea40a3c3ebe0533e6e32990d84af92235a3d26b4a sparql-client (3.2.2) sshkit (1.25.0) sha256=c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744 systemu (2.6.5) sha256=01f7d014b1453b28e5781e15c4d7d63fc9221c29b174b7aae5253207a75ab33e @@ -783,4 +753,4 @@ CHECKSUMS webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH - 4.0.7 + 4.0.5 From 7b122a344ce0c80f9f83e3615e31f69957f32dd5 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 27 Feb 2026 16:28:43 -0800 Subject: [PATCH 084/173] remove .second for compatiblty reasons --- config/rack_attack.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/rack_attack.rb b/config/rack_attack.rb index 4612b4935..e24e05fbb 100644 --- a/config/rack_attack.rb +++ b/config/rack_attack.rb @@ -29,11 +29,11 @@ request.env['REMOTE_USER']&.admin? end -Rack::Attack.throttle('req/ip/heavy', limit: limit_req_ip_heavy, period: 1.second) do |req| +Rack::Attack.throttle('req/ip/heavy', limit: limit_req_ip_heavy, period: 1) do |req| req.ip if req.path.include?('/recommender') || req.path.include?('/annotator') end -Rack::Attack.throttle('req/ip', limit: limit_req_ip, period: 1.second) do |req| +Rack::Attack.throttle('req/ip', limit: limit_req_ip, period: 1) do |req| req.ip end From 9a9584682f4fee2b1172c8b4dc786abe1ece2bcc Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 27 Feb 2026 16:36:04 -0800 Subject: [PATCH 085/173] Gemfile.lock update --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 59cab63a4..b16cddbdd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 13a8559a2346cc8320d7d36046646907bfa8a27c + revision: f6310650f578200f0e1465bd013dc5a737ef0170 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -29,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 + revision: 4344c70a1684d39e58272f695b823f7eec4ac13c branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -120,7 +120,7 @@ GEM securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) - addressable (2.8.8) + addressable (2.8.9) public_suffix (>= 2.0.2, < 8.0) airbrussh (1.6.0) sshkit (>= 1.6.1, != 1.7.0) @@ -567,7 +567,7 @@ DEPENDENCIES CHECKSUMS activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae - addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485 airbrussh (1.6.0) sha256=7e2cf581f2319d2c2b2b672c9fc486efb4dfcfed4bd2dadbef5f10b8b2a000d0 ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 From 1f8c6956d6e505a60c8cfdd5ebb9224b146345e7 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 3 Mar 2026 15:46:11 -0800 Subject: [PATCH 086/173] fixed the @context not showing in home API service call --- controllers/home_controller.rb | 24 ++++++++++++++++++++---- test/controllers/test_home_controller.rb | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/controllers/home_controller.rb b/controllers/home_controller.rb index e9140d6dd..2d2490f53 100644 --- a/controllers/home_controller.rb +++ b/controllers/home_controller.rb @@ -221,8 +221,8 @@ def routes_list navigable_routes end - # Sinatra < 4 routes were objects; Sinatra 4 routes are arrays. - # Normalize both to a common hash used by this controller. + # Sinatra < 4 routes are route objects; Sinatra 4 routes are arrays. + # Normalize both to a common shape. def parse_route(method, route) if route.respond_to?(:path) && route.respond_to?(:file) return { verb: route.verb.to_s, path: route.path.to_s.split("?").first, file: route.file } @@ -230,8 +230,24 @@ def parse_route(method, route) if route.is_a?(Array) pattern = route[0] - route_block = route[-1] - file = route_block.respond_to?(:source_location) ? route_block.source_location&.first : nil + wrapper_proc = route[-1] + original_block = nil + file = nil + + if wrapper_proc.respond_to?(:binding) + begin + route_binding = wrapper_proc.binding + if route_binding.local_variables.include?(:block) + original_block = route_binding.local_variable_get(:block) + end + rescue StandardError + # ignore and leave file nil + end + end + + if original_block.respond_to?(:source_location) + file = original_block.source_location&.first + end return { verb: method.to_s, path: pattern.to_s.split("?").first, file: file } end diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index 1bade976c..bc4e64b9d 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -8,6 +8,9 @@ def test_home_index_returns_links_hash body = MultiJson.load(last_response.body) assert body.key?('links') assert_kind_of Hash, body['links'] + assert body['links'].key?('@context') + assert_kind_of Hash, body['links']['@context'] + assert_operator body['links']['@context'].length, :>, 0 end def test_home_index_handles_type_uri_failures From d6d17cf084028453425a97bb5c6236ca7522d3de Mon Sep 17 00:00:00 2001 From: = Date: Tue, 3 Mar 2026 15:46:38 -0800 Subject: [PATCH 087/173] Gemfile.lock update --- Gemfile.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index cb158cd79..141ee9afb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 13a8559a2346cc8320d7d36046646907bfa8a27c + revision: fb4e00f8928867fc6bce953b4aa8f946c793e7cd branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -106,7 +106,7 @@ GIT GIT remote: https://github.com/sinatra/sinatra.git - revision: 9e5c4ec8ade92c7375f44acf4c6e1103d32d6c12 + revision: f891dd2b6f4911e356600efe6c3b82af97d262c6 specs: rack-protection (4.2.1) base64 (>= 0.1.0) @@ -135,7 +135,7 @@ GEM securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) - addressable (2.8.8) + addressable (2.8.9) public_suffix (>= 2.0.2, < 8.0) airbrussh (1.6.0) sshkit (>= 1.6.1, != 1.7.0) @@ -304,13 +304,13 @@ GEM net-imap net-pop net-smtp - mcp (0.7.1) + mcp (0.8.0) json-schema (>= 4.1) method_source (1.1.0) mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0224) + mime-types-data (3.2026.0303) mini_mime (1.1.5) minitest (6.0.2) drb (~> 2.0) @@ -370,7 +370,7 @@ GEM coderay (~> 1.1) method_source (~> 1.0) reline (>= 0.6.0) - public_suffix (7.0.2) + public_suffix (7.0.5) raabro (1.4.0) racc (1.8.1) rack (3.2.5) @@ -589,7 +589,7 @@ DEPENDENCIES CHECKSUMS activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae - addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485 airbrussh (1.6.0) sha256=7e2cf581f2319d2c2b2b672c9fc486efb4dfcfed4bd2dadbef5f10b8b2a000d0 ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 @@ -678,10 +678,10 @@ CHECKSUMS logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 - mcp (0.7.1) sha256=fa967895d6952bad0d981ea907731d8528d2c246d2079d56a9c8bae83d14f1c7 + mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0224) sha256=bea02e0168b37f6935696c4fcfeb3374a0a62e82e6187af5f3f3b709bf67e5fd + mime-types-data (3.2026.0303) sha256=164af1de5824c5195d4b503b0a62062383b65c08671c792412450cd22d3bc224 mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 @@ -716,7 +716,7 @@ CHECKSUMS pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e - public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3 From 3b9db9b0e6769d8bff5e555499e9d1afe6693751 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 3 Mar 2026 21:15:39 -0800 Subject: [PATCH 088/173] Gemfile.lock update --- .ruby-version | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ruby-version b/.ruby-version index e650c01d9..f15386a5d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.9 +3.2.10 diff --git a/Gemfile.lock b/Gemfile.lock index 992e621f5..7092cf0de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: fb4e00f8928867fc6bce953b4aa8f946c793e7cd + revision: 71385a8db443e5fcdfe4910404208e49f49f83b3 branch: ontoportal-lirmm-development specs: goo (0.0.2) From 829513d01efa9353264b95e25cd9ac8067193f23 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 4 Mar 2026 12:06:04 -0800 Subject: [PATCH 089/173] Gemfile.lock update --- Gemfile.lock | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7092cf0de..b54563c0b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 71385a8db443e5fcdfe4910404208e49f49f83b3 + revision: f803bb2784cc052032b8c55d4b9b43b5548532e8 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -29,7 +29,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 + revision: 4344c70a1684d39e58272f695b823f7eec4ac13c branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -174,15 +174,9 @@ GEM faraday (~> 2.0) ffi (1.17.3) ffi (1.17.3-aarch64-linux-gnu) - ffi (1.17.3-aarch64-linux-musl) - ffi (1.17.3-arm-linux-gnu) - ffi (1.17.3-arm-linux-musl) ffi (1.17.3-arm64-darwin) - ffi (1.17.3-x86-linux-gnu) - ffi (1.17.3-x86-linux-musl) ffi (1.17.3-x86_64-darwin) ffi (1.17.3-x86_64-linux-gnu) - ffi (1.17.3-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -215,7 +209,6 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) - google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -241,9 +234,6 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.70.1-x86-linux) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -506,20 +496,11 @@ GEM webrick (1.9.2) PLATFORMS - aarch64-linux aarch64-linux-gnu - aarch64-linux-musl - arm-linux-gnu - arm-linux-musl arm64-darwin ruby - x86-linux - x86-linux-gnu - x86-linux-musl x86_64-darwin - x86_64-linux x86_64-linux-gnu - x86_64-linux-musl DEPENDENCIES activesupport @@ -619,15 +600,9 @@ CHECKSUMS faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 - ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 - ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 - ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f - ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 - ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f - ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -641,7 +616,6 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c - google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -650,7 +624,6 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 - grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -778,4 +751,4 @@ CHECKSUMS webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH - 4.0.7 + 4.0.7 From 60ae1fff3ff5e819abd71f8f48d2ed0dd490a0b6 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 4 Mar 2026 13:52:02 -0800 Subject: [PATCH 090/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b54563c0b..bd90ad7a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 637fdfcfc0f9201a631b4d827d34aa8993325565 + revision: 4db7da9900c892ec9ff9a2fddfe9ab809e59caee branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -751,4 +751,4 @@ CHECKSUMS webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH - 4.0.7 + 4.0.7 From 041553bdfffe5876888ec2685b259811b70d445f Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Thu, 5 Mar 2026 15:58:38 -0800 Subject: [PATCH 091/173] re-added the use of shotgun, pointed to the updated version from syphax-bouazzouni/shotgun --- Gemfile | 1 + Gemfile.lock | 15 +++++++++++++-- app.rb | 3 --- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 922951679..bb2acbdd5 100644 --- a/Gemfile +++ b/Gemfile @@ -55,6 +55,7 @@ gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branc gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' group :development do + gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' gem 'rubocop' end diff --git a/Gemfile.lock b/Gemfile.lock index 992e621f5..a43bcb4e1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ncbo/goo.git - revision: fb4e00f8928867fc6bce953b4aa8f946c793e7cd + revision: 93c8ade0f7ef56fa4ad4fbdee0f9c6c4553be287 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 637fdfcfc0f9201a631b4d827d34aa8993325565 + revision: 4db7da9900c892ec9ff9a2fddfe9ab809e59caee branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -104,6 +104,15 @@ GIT ffi (~> 1.15) rdf (~> 3.3) +GIT + remote: https://github.com/syphax-bouazzouni/shotgun.git + revision: 421f4d0bc2f3193f7cd4b634f5f8ccab09f6b0f7 + branch: master + specs: + shotgun (0.9.2) + rack + rackup + GEM remote: https://rubygems.org/ specs: @@ -572,6 +581,7 @@ DEPENDENCIES request_store rexml rubocop + shotgun! simplecov simplecov-cobertura sinatra @@ -753,6 +763,7 @@ CHECKSUMS rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + shotgun (0.9.2) signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5 diff --git a/app.rb b/app.rb index 975fe5b64..08ed31a42 100644 --- a/app.rb +++ b/app.rb @@ -82,9 +82,6 @@ # Development-specific options if [:development, :console].include?(settings.environment) require 'pry' # Debug by placing 'binding.pry' where you want the interactive console to start - require 'sinatra/reloader' - register Sinatra::Reloader - also_reload './{config,controllers,helpers,models,lib}/**/*.rb' # Show exceptions set :raise_errors, true set :dump_errors, false From 2a04c0236031702172aace51393beec8e23dca3f Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Thu, 5 Mar 2026 16:12:41 -0800 Subject: [PATCH 092/173] Gemfile.lock update --- Gemfile.lock | 792 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 792 insertions(+) create mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..8a2ba0558 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,792 @@ +GIT + remote: https://github.com/ncbo/goo.git + revision: 93c8ade0f7ef56fa4ad4fbdee0f9c6c4553be287 + branch: ontoportal-lirmm-development + specs: + goo (0.0.2) + addressable (~> 2.8) + pry + rdf + rdf-raptor + rdf-rdfxml + rdf-vocab + redis + rest-client + rsolr + sparql-client + uuid + +GIT + remote: https://github.com/ncbo/ncbo_annotator.git + revision: e86ece03c2d80604cdea4d96bd1de6899f6b4762 + branch: chore/ruby3.2-minitest6-compat + specs: + ncbo_annotator (0.0.1) + goo + ontologies_linked_data + redis + ruby-xxHash + +GIT + remote: https://github.com/ncbo/ncbo_cron.git + revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 + branch: chore/ontoportal-lirmm-goo-compat + specs: + ncbo_cron (0.0.1) + dante + faraday (~> 2) + faraday-follow_redirects (~> 0) + goo + google-analytics-data + mlanett-redis-lock + multi_json + ncbo_annotator + ontologies_linked_data + redis + rufus-scheduler (~> 3.9) + +GIT + remote: https://github.com/ncbo/ncbo_ontology_recommender.git + revision: 911f88f75814618f2c39d602c56d9f57245f46da + branch: chore/ruby3.2-minitest6-compat + specs: + ncbo_ontology_recommender (0.0.1) + goo + ncbo_annotator + ontologies_linked_data + redis + +GIT + remote: https://github.com/ncbo/ontologies_linked_data.git + revision: 790ac6dd95924e81bde8f6956dce3d20b3719c04 + branch: chore/ontoportal-lirmm-goo-compat + specs: + ontologies_linked_data (0.0.1) + activesupport + bcrypt + down (~> 5.0) + goo + json + libxml-ruby + multi_json + net-ftp + oj + omni_logger + pony + rack + rack-test + rsolr + rubyzip (~> 3.0) + +GIT + remote: https://github.com/ncbo/sparql-client.git + revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 + branch: ontoportal-lirmm-development + specs: + sparql-client (3.2.2) + net-http-persistent (~> 4.0, >= 4.0.2) + rdf (~> 3.2, >= 3.2.11) + +GIT + remote: https://github.com/palexander/rack-post-body-to-params.git + revision: 0fd30e710386d0cb8a3a6833d9549d7b655d5398 + branch: multipart_support + specs: + rack-post-body-to-params (0.1.8) + activesupport (>= 2.3) + +GIT + remote: https://github.com/ruby-rdf/rdf-raptor.git + revision: 6392ceabf71c3233b0f7f0172f662bd4a22cd534 + ref: 6392ceabf71c3233b0f7f0172f662bd4a22cd534 + specs: + rdf-raptor (3.3.0) + ffi (~> 1.15) + rdf (~> 3.3) + +GIT + remote: https://github.com/syphax-bouazzouni/shotgun.git + revision: 421f4d0bc2f3193f7cd4b634f5f8ccab09f6b0f7 + branch: master + specs: + shotgun (0.9.2) + rack + rackup + +GEM + remote: https://rubygems.org/ + specs: + activesupport (8.1.2) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.9) + public_suffix (>= 2.0.2, < 8.0) + airbrussh (1.6.1) + sshkit (>= 1.6.1, != 1.7.0) + ansi (1.5.0) + ast (2.4.3) + base64 (0.3.0) + bcp47_spec (0.2.1) + bcrypt (3.1.21) + bcrypt_pbkdf (1.1.2) + bcrypt_pbkdf (1.1.2-arm64-darwin) + bcrypt_pbkdf (1.1.2-x86_64-darwin) + bigdecimal (4.0.1) + builder (3.3.0) + byebug (12.0.0) + capistrano (3.20.0) + airbrussh (>= 1.0.0) + i18n + rake (>= 10.0.0) + sshkit (>= 1.9.0) + capistrano-bundler (2.2.0) + capistrano (~> 3.1) + capistrano-locally (0.3.0) + capistrano (~> 3.0) + capistrano-rbenv (2.2.0) + capistrano (~> 3.1) + sshkit (~> 1.3) + coderay (1.1.3) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) + crack (0.4.5) + rexml + dante (0.2.0) + date (3.5.1) + docile (1.4.1) + domain_name (0.6.20240107) + down (5.4.2) + addressable (~> 2.8) + drb (2.2.3) + ed25519 (1.4.0) + et-orbi (1.4.0) + tzinfo + faraday (2.14.1) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-follow_redirects (0.5.0) + faraday (>= 1, < 3) + faraday-net_http (3.4.2) + net-http (~> 0.5) + faraday-retry (2.4.0) + faraday (~> 2.0) + ffi (1.17.3) + ffi (1.17.3-aarch64-linux-gnu) + ffi (1.17.3-aarch64-linux-musl) + ffi (1.17.3-arm-linux-gnu) + ffi (1.17.3-arm-linux-musl) + ffi (1.17.3-arm64-darwin) + ffi (1.17.3-x86-linux-gnu) + ffi (1.17.3-x86-linux-musl) + ffi (1.17.3-x86_64-darwin) + ffi (1.17.3-x86_64-linux-gnu) + ffi (1.17.3-x86_64-linux-musl) + fugit (1.12.1) + et-orbi (~> 1.4) + raabro (~> 1.4) + gapic-common (1.1.0) + faraday (>= 1.9, < 3.a) + faraday-retry (>= 1.0, < 3.a) + google-cloud-env (~> 2.2) + google-logging-utils (~> 0.1) + google-protobuf (>= 3.25, < 5.a) + googleapis-common-protos (~> 1.6) + googleapis-common-protos-types (~> 1.15) + googleauth (~> 1.12) + grpc (~> 1.66) + get_process_mem (0.2.7) + ffi (~> 1.0) + google-analytics-data (0.7.2) + google-analytics-data-v1beta (>= 0.11, < 2.a) + google-cloud-core (~> 1.6) + google-analytics-data-v1beta (0.17.0) + gapic-common (~> 1.0) + google-cloud-errors (~> 1.0) + google-cloud-core (1.8.0) + google-cloud-env (>= 1.0, < 3.a) + google-cloud-errors (~> 1.0) + google-cloud-env (2.3.1) + base64 (~> 0.2) + faraday (>= 1.0, < 3.a) + google-cloud-errors (1.5.0) + google-logging-utils (0.2.0) + google-protobuf (3.25.3) + google-protobuf (3.25.3-aarch64-linux) + google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86-linux) + google-protobuf (3.25.3-x86_64-darwin) + google-protobuf (3.25.3-x86_64-linux) + googleapis-common-protos (1.8.0) + google-protobuf (>= 3.18, < 5.a) + googleapis-common-protos-types (~> 1.20) + grpc (~> 1.41) + googleapis-common-protos-types (1.20.0) + google-protobuf (>= 3.18, < 5.a) + googleauth (1.16.2) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.2) + google-logging-utils (~> 0.1) + jwt (>= 1.4, < 4.0) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + grpc (1.70.1) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-aarch64-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-arm64-darwin) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86_64-darwin) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86_64-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + haml (5.2.2) + temple (>= 0.8.0) + tilt + hashdiff (1.2.1) + htmlentities (4.4.2) + http-accept (1.7.0) + http-cookie (1.1.0) + domain_name (~> 0.5) + i18n (1.14.8) + concurrent-ruby (~> 1.0) + io-console (0.8.2) + json (2.18.1) + json-canonicalization (0.4.0) + json-ld (3.2.5) + htmlentities (~> 4.3) + json-canonicalization (~> 0.3, >= 0.3.2) + link_header (~> 0.0, >= 0.0.8) + multi_json (~> 1.15) + rack (>= 2.2, < 4) + rdf (~> 3.2, >= 3.2.10) + json-schema (6.1.0) + addressable (~> 2.8) + bigdecimal (>= 3.1, < 5) + jwt (3.1.2) + base64 + kgio (2.11.4) + language_server-protocol (3.17.0.5) + libxml-ruby (5.0.5) + link_header (0.0.8) + lint_roller (1.1.0) + logger (1.7.0) + macaddr (1.7.2) + systemu (~> 2.6.5) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + mcp (0.8.0) + json-schema (>= 4.1) + method_source (1.1.0) + mime-types (3.7.0) + logger + mime-types-data (~> 3.2025, >= 3.2025.0507) + mime-types-data (3.2026.0303) + mini_mime (1.1.5) + minitest (6.0.2) + drb (~> 2.0) + prism (~> 1.5) + minitest-hooks (1.5.3) + minitest (> 5.3) + minitest-reporters (1.7.1) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + minitest-stub_any_instance (1.0.3) + mlanett-redis-lock (0.2.7) + redis + multi_json (1.19.1) + mustermann (3.0.4) + ruby2_keywords (~> 0.0.1) + net-ftp (0.3.9) + net-protocol + time + net-http (0.9.1) + uri (>= 0.11.1) + net-http-persistent (4.0.8) + connection_pool (>= 2.2.4, < 4) + net-imap (0.6.3) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-scp (4.1.0) + net-ssh (>= 2.6.5, < 8.0.0) + net-sftp (4.0.0) + net-ssh (>= 5.0.0, < 8.0.0) + net-smtp (0.5.1) + net-protocol + net-ssh (7.3.0) + netrc (0.11.0) + oj (3.16.15) + bigdecimal (>= 3.0) + ostruct (>= 0.2) + omni_logger (0.1.4) + logger + os (1.1.4) + ostruct (0.6.3) + pandoc-ruby (2.1.10) + parallel (1.27.0) + parseconfig (1.1.2) + parser (3.3.10.2) + ast (~> 2.4.1) + racc + pony (1.13.1) + mail (>= 2.0) + prism (1.9.0) + pry (0.16.0) + coderay (~> 1.1) + method_source (~> 1.0) + reline (>= 0.6.0) + public_suffix (7.0.5) + raabro (1.4.0) + racc (1.8.1) + rack (3.2.5) + rack-accept (0.4.5) + rack (>= 0.4) + rack-attack (6.8.0) + rack (>= 1.0, < 4) + rack-cache (1.17.0) + rack (>= 0.4) + rack-contrib (2.5.0) + rack (< 4) + rack-cors (3.0.0) + logger + rack (>= 3.0.14) + rack-mini-profiler (4.0.1) + rack (>= 1.2.0) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rack-timeout (0.7.0) + rackup (2.3.1) + rack (>= 3) + rainbow (3.1.1) + raindrops (0.20.1) + rake (13.3.1) + rdf (3.3.1) + bcp47_spec (~> 0.2) + link_header (~> 0.0, >= 0.0.8) + rdf-rdfxml (3.3.0) + builder (~> 3.2, >= 3.2.4) + htmlentities (~> 4.3) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + rdf-vocab (3.3.3) + rdf (~> 3.3) + rdf-xsd (3.3.0) + rdf (~> 3.3) + rexml (~> 3.2) + redis (5.4.1) + redis-client (>= 0.22.0) + redis-client (0.26.4) + connection_pool + redis-rack-cache (2.2.1) + rack-cache (>= 1.10, < 2) + redis-store (>= 1.6, < 2) + redis-store (1.11.0) + redis (>= 4, < 6) + regexp_parser (2.11.3) + reline (0.6.3) + io-console (~> 0.5) + request_store (1.7.0) + rack (>= 1.4) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + rexml (3.4.4) + rsolr (2.6.0) + builder (>= 2.1.2) + faraday (>= 0.9, < 3, != 2.0.0) + rubocop (1.85.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + mcp (~> 0.6) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + ruby-progressbar (1.13.0) + ruby-xxHash (0.4.0.2) + ruby2_keywords (0.0.5) + rubyzip (3.2.2) + rufus-scheduler (3.9.2) + fugit (~> 1.1, >= 1.11.1) + securerandom (0.4.1) + signet (0.21.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 4.0) + multi_json (~> 1.10) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-cobertura (3.1.0) + rexml + simplecov (~> 0.19) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + sinatra (4.2.1) + logger (>= 1.6.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.2.1) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) + sinatra-contrib (4.2.1) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.2.1) + sinatra (= 4.2.1) + tilt (~> 2.0) + sshkit (1.25.0) + base64 + logger + net-scp (>= 1.1.2) + net-sftp (>= 2.1.2) + net-ssh (>= 2.8.0) + ostruct + systemu (2.6.5) + temple (0.10.4) + tilt (2.7.0) + time (0.4.2) + date + timeout (0.6.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + unicorn (6.1.0) + kgio (~> 2.6) + raindrops (~> 0.7) + unicorn-worker-killer (0.4.5) + get_process_mem (~> 0) + unicorn (>= 4, < 7) + uri (1.1.1) + uuid (2.3.9) + macaddr (~> 1.0) + webmock (3.26.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + webrick (1.9.2) + +PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + activesupport + bcrypt_pbkdf (>= 1.0, < 2.0) + bigdecimal + byebug (~> 12.0) + capistrano (~> 3) + capistrano-bundler + capistrano-locally + capistrano-rbenv + crack (= 0.4.5) + ed25519 (>= 1.2, < 2.0) + ffi + goo! + google-protobuf (= 3.25.3) + grpc (= 1.70.1) + haml (~> 5.2.2) + json-ld (~> 3.2.0) + json-schema + minitest + minitest-hooks + minitest-reporters + minitest-stub_any_instance + multi_json + ncbo_annotator! + ncbo_cron! + ncbo_ontology_recommender! + net-ftp + oj + ontologies_linked_data! + pandoc-ruby + parallel + parseconfig + rack + rack-accept + rack-attack + rack-cache + rack-contrib + rack-cors + rack-mini-profiler + rack-post-body-to-params! + rack-test + rack-timeout + rackup + rake + rdf-raptor! + redis + redis-rack-cache + redis-store + request_store + rexml + rubocop + shotgun! + simplecov + simplecov-cobertura + sinatra + sinatra-contrib + sparql-client! + unicorn + unicorn-worker-killer + webmock + webrick + +CHECKSUMS + activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae + addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485 + airbrussh (1.6.1) sha256=9a5fc95583cefe722054a016d26ff0338cf00072b031b829086dde2039d5836a + ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bcp47_spec (0.2.1) sha256=3fd62edf96c126bd9624e4319ac74082a966081859d1ee0ef3c3041640a37810 + bcrypt (3.1.21) sha256=5964613d750a42c7ee5dc61f7b9336fb6caca429ba4ac9f2011609946e4a2dcf + bcrypt_pbkdf (1.1.2) sha256=c2414c23ce66869b3eb9f643d6a3374d8322dfb5078125c82792304c10b94cf6 + bcrypt_pbkdf (1.1.2-arm64-darwin) sha256=afdd6feb6ed5a97b8e44caacb3f2d641b98af78e6a516d4a3520b69af5cf9fea + bcrypt_pbkdf (1.1.2-x86_64-darwin) sha256=35f5639d0058e6c2cc2f856f9c0b14080543268d3047abe6bc81c513093caa0e + bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e + capistrano (3.20.0) sha256=0113e58dda99add0342e56a244f664734c59f442c5ed734f5303b0b559b479c9 + capistrano-bundler (2.2.0) sha256=47b4cf2ea17ea132bb0a5cabc5663443f5190a54f4da5b322d04e1558ff1468c + capistrano-locally (0.3.0) sha256=ad44252f19641e8dd980f7cb0241e9ac11919b1f4cbdb642d272a6d0edcb84eb + capistrano-rbenv (2.2.0) sha256=3c8f39b7c624f3806630dcb475484bb3579aef07a40efe85089d83f64b0c35f5 + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a + crack (0.4.5) sha256=798416fb29b8c9f655d139d5559169b39c4a0a3b8f8f39b7f670eec1af9b21b3 + dante (0.2.0) sha256=939776f04b4d253ffbbcf53341631aa2ee6e6cf314dedade2e60ac43b40a6fe6 + date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 + docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 + down (5.4.2) sha256=516e5e01e7a96214a7e2cd155aac6f700593038ae6c857c0f4a05413b1c58acf + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 + et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc + faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c + faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad + faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c + faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe + ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c + ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 + ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 + ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 + ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 + ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f + ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 + ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 + ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 + ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f + ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 + fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 + gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 + get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba + goo (0.0.2) + google-analytics-data (0.7.2) sha256=5e4bf6dc575c7725c2b32541725749890a88e0a64ff0ad7e8a73f75ad5a1bbc9 + google-analytics-data-v1beta (0.17.0) sha256=1145d30d794bcf6bf8b723140a0ee2c445e740b82cf4051a31d992e7393168a6 + google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf + google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7 + google-cloud-errors (1.5.0) sha256=b56be28b8c10628125214dde571b925cfcebdbc58619e598250c37a2114f7b4b + google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b + google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 + google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 + google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c + google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 + google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 + google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 + googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe + googleapis-common-protos-types (1.20.0) sha256=5e374b06bcfc7e13556e7c0d87b99f1fa3d42de6396a1de3d8fc13aefb4dd07f + googleauth (1.16.2) sha256=15009502e2e38af71948cda918f230e27d327f6882a1e47967a5a4664930a638 + grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb + grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 + grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 + grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 + grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 + grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be + haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c + hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 + htmlentities (4.4.2) sha256=bbafbdf69f2eca9262be4efef7e43e6a1de54c95eb600f26984f71d2fe96c5c3 + http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 + http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 + i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986 + json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef + json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc + json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 + jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 + kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + libxml-ruby (5.0.5) sha256=f1bc07152982df555d70159a694ee2a53539de2cdad4b3c8a447fbb15e7e4e9a + link_header (0.0.8) sha256=15c65ce43b29f739b30d05e5f25c22c23797e89cf6f905dbb595fb4c70cb55f9 + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 + mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 + mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 + mime-types-data (3.2026.0303) sha256=164af1de5824c5195d4b503b0a62062383b65c08671c792412450cd22d3bc224 + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d + minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 + minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c + minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 + mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 + multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 + mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22 + ncbo_annotator (0.0.1) + ncbo_cron (0.0.1) + ncbo_ontology_recommender (0.0.1) + net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 + net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 + net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 + net-imap (0.6.3) sha256=9bab75f876596d09ee7bf911a291da478e0cd6badc54dfb82874855ccc82f2ad + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d + net-sftp (4.0.0) sha256=65bb91c859c2f93b09826757af11b69af931a3a9155050f50d1b06d384526364 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 + netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f + oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd + omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e + ontologies_linked_data (0.0.1) + os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f + ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 + pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 + parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357 + pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e + public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 + raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3 + rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 + rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2 + rack-cache (1.17.0) sha256=49592f3ef2173b0f5524df98bb801fb411e839869e7ce84ac428dc492bf0eb90 + rack-contrib (2.5.0) sha256=51bd2ce82b8a3270f9173130c4cdaea72aab8b03dce8cd6af1c4344d84a32d02 + rack-cors (3.0.0) sha256=7b95be61db39606906b61b83bd7203fa802b0ceaaad8fcb2fef39e097bf53f68 + rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78 + rack-post-body-to-params (0.1.8) + rack-protection (4.2.1) sha256=cf6e2842df8c55f5e4d1a4be015e603e19e9bc3a7178bae58949ccbb58558bac + rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 + rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + raindrops (0.20.1) sha256=aa0eb9ff6834f2d9e232ba688bd49cb30be893bc5a3452e74722c94c1fab4730 + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + rdf (3.3.1) sha256=dda6a2c95198915fc63d66ee270e35d4a76d431720747a2cf97ecd92062fa150 + rdf-raptor (3.3.0) + rdf-rdfxml (3.3.0) sha256=11647f6111b97b6a9b82413bd9810d4bb5524aa7dd06b3c1330bf58ec3aa6a9a + rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b + rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 + redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae + redis-client (0.26.4) sha256=3ad70beff5da2653e02dfeae996e7d8d7147a558da12b16b2282ad345e4c7120 + redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 + redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 + regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb + rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b + rubocop (1.85.1) sha256=3dbcf9e961baa4c376eeeb2a03913dca5e3987033b04d38fa538aa1e7406cc77 + rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 + ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef + rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c + rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + shotgun (0.9.2) + signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b + simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 + simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5 + simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 + simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080 + sinatra-contrib (4.2.1) sha256=10d091c944d268aa910c618ea40a3c3ebe0533e6e32990d84af92235a3d26b4a + sparql-client (3.2.2) + sshkit (1.25.0) sha256=c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744 + systemu (2.6.5) sha256=01f7d014b1453b28e5781e15c4d7d63fc9221c29b174b7aae5253207a75ab33e + temple (0.10.4) sha256=b7a1e94b6f09038ab0b6e4fe0126996055da2c38bec53a8a336f075748fff72c + tilt (2.7.0) sha256=0d5b9ba69f6a36490c64b0eee9f6e9aad517e20dcc848800a06eb116f08c6ab3 + time (0.4.2) sha256=f324e498c3bde9471d45a7d18f874c27980e9867aa5cfca61bebf52262bc3dab + timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + unicorn (6.1.0) sha256=45dd987add4c2b084c1880a68373af42797a704ad7441faff9b14b4982aa0fc0 + unicorn-worker-killer (0.4.5) sha256=fc3c5dae71566c9e2a165dfbf75664f7bc16fec20251a1d09c3375ffe58b3991 + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 + uuid (2.3.9) sha256=aec0cf592053cd6e07c13c1ef94c440aba705f22eb1ee767b39631f2760124d7 + webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 + webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 + +BUNDLED WITH + 4.0.7 From b987bbdce79b4eb33219b1f380e0fb384487d744 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 6 Mar 2026 16:41:22 -0800 Subject: [PATCH 093/173] integrate ontoportal testkit --- .github/workflows/ruby-unit-tests.yml | 30 ----- .github/workflows/testkit-unit-tests.yml | 87 +++++++++++++ .ontoportal-testkit.yml | 9 ++ Dockerfile | 30 ++--- Gemfile | 3 +- Gemfile.lock | 38 +++--- config/environments/test.rb | 55 +++------ docker-compose.yml | 150 ----------------------- rakelib/ontoportal_testkit.rake | 2 + 9 files changed, 155 insertions(+), 249 deletions(-) delete mode 100644 .github/workflows/ruby-unit-tests.yml create mode 100644 .github/workflows/testkit-unit-tests.yml create mode 100644 .ontoportal-testkit.yml delete mode 100644 docker-compose.yml create mode 100644 rakelib/ontoportal_testkit.rake diff --git a/.github/workflows/ruby-unit-tests.yml b/.github/workflows/ruby-unit-tests.yml deleted file mode 100644 index 2aac14680..000000000 --- a/.github/workflows/ruby-unit-tests.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Ruby Unit Tests - -on: - push: - pull_request: - -jobs: - test: - strategy: - fail-fast: false - matrix: - backend: ['api', 'api-agraph'] # api runs tests with 4store backend and api-agraph runs with AllegroGraph backend - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Build docker-compose - run: docker compose --profile 4store build #profile flag is set in order to build all containers in this step - - name: Run unit tests - # unit tests are run inside a container - # http://docs.codecov.io/docs/testing-with-docker - run: | - ci_env=`bash <(curl -s https://codecov.io/env)` - docker compose run $ci_env -e CI --rm ${{ matrix.backend }} bundle exec rake test TESTOPTS='-v' - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - flags: unittests - verbose: true - fail_ci_if_error: false # optional (default = false) diff --git a/.github/workflows/testkit-unit-tests.yml b/.github/workflows/testkit-unit-tests.yml new file mode 100644 index 000000000..b5fe5ba83 --- /dev/null +++ b/.github/workflows/testkit-unit-tests.yml @@ -0,0 +1,87 @@ +name: Docker Unit Tests + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + pull_request: + +env: + # CI execution mode for backend tests: + # - container: run `test:docker::container` (default) + # - native: run `test:docker:` on host Ruby + OPTK_CI_RUN_MODE: ${{ vars.OPTK_CI_RUN_MODE || 'container' }} + # Example override to force native mode in this workflow file: + # OPTK_CI_RUN_MODE: native + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + backends: ${{ steps.cfg.outputs.backends }} + steps: + - uses: actions/checkout@v4 + + - id: cfg + name: Read backend matrix from .ontoportal-testkit.yml + run: | + BACKENDS=$(ruby -ryaml -rjson -e 'c=YAML.safe_load_file(".ontoportal-testkit.yml") || {}; b=c["backends"] || %w[fs ag vo gd]; puts JSON.generate(b)') + echo "backends=$BACKENDS" >> "$GITHUB_OUTPUT" + + test: + needs: prepare + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + backend: ${{ fromJson(needs.prepare.outputs.backends) }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Ruby from .ruby-version + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Set up Java 11 (native mode) + if: env.OPTK_CI_RUN_MODE == 'native' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '11' + + - name: Install native system dependencies + if: env.OPTK_CI_RUN_MODE == 'native' + run: | + sudo apt-get update + sudo apt-get install -y raptor2-utils + + - name: Run unit tests + env: + CI: "true" + TESTOPTS: "-v" + BACKEND: ${{ matrix.backend }} + run: | + MODE="${OPTK_CI_RUN_MODE:-container}" + TASK="test:docker:${BACKEND}" + if [ "$MODE" = "container" ]; then + TASK="${TASK}:container" + elif [ "$MODE" != "native" ]; then + echo "Invalid OPTK_CI_RUN_MODE=$MODE (expected container or native)" + exit 1 + fi + + bundle exec rake "$TASK" + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + flags: unittests,${{ matrix.backend }} + verbose: true + fail_ci_if_error: false diff --git a/.ontoportal-testkit.yml b/.ontoportal-testkit.yml new file mode 100644 index 000000000..c63def5c1 --- /dev/null +++ b/.ontoportal-testkit.yml @@ -0,0 +1,9 @@ +component_name: ontologies_api +app_service: test-container +backends: + - fs + - ag + - vo + - gd +dependency_services: + - mgrep diff --git a/Dockerfile b/Dockerfile index 896b90cb4..3ca8019ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,20 @@ -ARG RUBY_VERSION=3.1 -ARG DISTRO_NAME=bullseye +ARG RUBY_VERSION=3.2 +ARG DISTRO=bullseye +ARG TESTKIT_BASE_IMAGE=ontoportal/testkit-base:ruby${RUBY_VERSION}-${DISTRO} +FROM ${TESTKIT_BASE_IMAGE} -FROM ruby:$RUBY_VERSION-$DISTRO_NAME +WORKDIR /app -RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ - openjdk-11-jre-headless \ - raptor2-utils \ - && rm -rf /var/lib/apt/lists/* +COPY Gemfile* *.gemspec ./ -RUN mkdir -p /srv/ontoportal/ontologies_api -RUN mkdir -p /srv/ontoportal/bundle -COPY Gemfile* /srv/ontoportal/ontologies_api/ +# Respect the project's Bundler lock when present. +RUN if [ -f Gemfile.lock ]; then \ + BUNDLER_VERSION=$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1 | tr -d ' '); \ + gem install bundler -v "$BUNDLER_VERSION"; \ + fi -WORKDIR /srv/ontoportal/ontologies_api +RUN bundle install --jobs 4 --retry 3 -ENV BUNDLE_PATH=/srv/ontoportal/bundle -RUN bundle install +COPY . ./ -COPY . /srv/ontoportal/ontologies_api -RUN cp /srv/ontoportal/ontologies_api/config/environments/config.rb.sample /srv/ontoportal/ontologies_api/config/environments/development.rb - -EXPOSE 9393 CMD ["bundle", "exec", "rackup", "-p", "9393", "--host", "0.0.0.0"] diff --git a/Gemfile b/Gemfile index 922951679..d4f6f3e12 100644 --- a/Gemfile +++ b/Gemfile @@ -77,8 +77,9 @@ group :test do gem 'crack', '0.4.5' gem 'minitest' gem 'minitest-hooks' - gem 'minitest-stub_any_instance' gem 'minitest-reporters' + gem 'minitest-stub_any_instance' + gem 'ontoportal_testkit', github: 'alexskr/ontoportal_testkit', branch: 'main' gem 'rack-test' gem 'simplecov', require: false gem 'simplecov-cobertura' # for codecov.io diff --git a/Gemfile.lock b/Gemfile.lock index b16cddbdd..2e9afb1e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,14 @@ +GIT + remote: https://github.com/alexskr/ontoportal_testkit.git + revision: 5138aa94c028ec97adeaf1f7a5ed9f1c40b12950 + branch: main + specs: + ontoportal_testkit (0.1.0) + rake (>= 13.0) + GIT remote: https://github.com/ncbo/goo.git - revision: f6310650f578200f0e1465bd013dc5a737ef0170 + revision: 93c8ade0f7ef56fa4ad4fbdee0f9c6c4553be287 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -18,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: e86ece03c2d80604cdea4d96bd1de6899f6b4762 + revision: 9da3081170369e842aecef94a5bde242d85bf6db branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -29,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 4344c70a1684d39e58272f695b823f7eec4ac13c + revision: ec1cfbb4f2153a00a06afc0b567cf9648e10db5a branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -58,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 637fdfcfc0f9201a631b4d827d34aa8993325565 + revision: 1f83c130045da5d9e0619ae3afc5a0d4a4ac390e branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -251,7 +259,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.18.1) + json (2.19.0) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -285,7 +293,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0224) + mime-types-data (3.2026.0303) mini_mime (1.1.5) minitest (6.0.2) drb (~> 2.0) @@ -345,7 +353,7 @@ GEM coderay (~> 1.1) method_source (~> 1.0) reline (>= 0.6.0) - public_suffix (7.0.2) + public_suffix (7.0.5) raabro (1.4.0) racc (1.8.1) rack (3.2.5) @@ -392,7 +400,7 @@ GEM rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.4) + redis-client (0.27.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -496,12 +504,10 @@ GEM webrick (1.9.2) PLATFORMS - aarch64-linux aarch64-linux-gnu arm64-darwin ruby x86_64-darwin - x86_64-linux x86_64-linux-gnu DEPENDENCIES @@ -533,6 +539,7 @@ DEPENDENCIES net-ftp oj ontologies_linked_data! + ontoportal_testkit! pandoc-ruby parallel parseconfig @@ -635,7 +642,7 @@ CHECKSUMS http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986 + json (2.19.0) sha256=bc5202f083618b3af7aba3184146ec9d820f8f6de261838b577173475e499d9a json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 @@ -651,7 +658,7 @@ CHECKSUMS mcp (0.7.1) sha256=fa967895d6952bad0d981ea907731d8528d2c246d2079d56a9c8bae83d14f1c7 method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0224) sha256=bea02e0168b37f6935696c4fcfeb3374a0a62e82e6187af5f3f3b709bf67e5fd + mime-types-data (3.2026.0303) sha256=164af1de5824c5195d4b503b0a62062383b65c08671c792412450cd22d3bc224 mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 @@ -677,6 +684,7 @@ CHECKSUMS oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) + ontoportal_testkit (0.1.0) os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 @@ -686,7 +694,7 @@ CHECKSUMS pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e - public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3 @@ -711,7 +719,7 @@ CHECKSUMS rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae - redis-client (0.26.4) sha256=3ad70beff5da2653e02dfeae996e7d8d7147a558da12b16b2282ad345e4c7120 + redis-client (0.27.0) sha256=00e5918c1ba3fcd54b28e7be24b36fbf7b073e842c3c021ac072173c3eac42bd redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 @@ -753,4 +761,4 @@ CHECKSUMS webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH - 4.0.5 + 2.7.2 diff --git a/config/environments/test.rb b/config/environments/test.rb index 26b69ebc4..2d19269bd 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,31 +1,16 @@ # conig file for unit tests -# GOO_BACKEND_NAME = ENV.include?("GOO_BACKEND_NAME") ? ENV["GOO_BACKEND_NAME"] : "AG" -# GOO_HOST = ENV.include?("GOO_HOST") ? ENV["GOO_HOST"] : "localhost" -# GOO_PATH_QUERY = ENV.include?("GOO_PATH_QUERY") ? ENV["GOO_PATH_QUERY"] : "/repositories/bioportal" -# GOO_PATH_DATA = ENV.include?("GOO_PATH_DATA") ? ENV["GOO_PATH_DATA"] : "/repositories/bioportal/statements" -# GOO_PATH_UPDATE = ENV.include?("GOO_PATH_UPDATE") ? ENV["GOO_PATH_UPDATE"] : "/repositories/bioportal/statements" -# GOO_PORT = ENV.include?("GOO_PORT") ? ENV["GOO_PORT"] : 10035 - -GOO_BACKEND_NAME = ENV.include?("GOO_BACKEND_NAME") ? ENV["GOO_BACKEND_NAME"] : "4store" -GOO_HOST = ENV.include?("GOO_HOST") ? ENV["GOO_HOST"] : "localhost" -GOO_PATH_DATA = ENV.include?("GOO_PATH_DATA") ? ENV["GOO_PATH_DATA"] : "/data/" -GOO_PATH_QUERY = ENV.include?("GOO_PATH_QUERY") ? ENV["GOO_PATH_QUERY"] : "/sparql/" -GOO_PATH_UPDATE = ENV.include?("GOO_PATH_UPDATE") ? ENV["GOO_PATH_UPDATE"] : "/update/" -GOO_PORT = ENV.include?("GOO_PORT") ? ENV["GOO_PORT"] : 9000 - -MGREP_DICTIONARY_FILE = ENV.include?("MGREP_DICTIONARY_FILE") ? ENV["MGREP_DICTIONARY_FILE"] : "./test/data/dictionary.txt" -MGREP_HOST = ENV.include?("MGREP_HOST") ? ENV["MGREP_HOST"] : "localhost" -MGREP_PORT = ENV.include?("MGREP_PORT") ? ENV["MGREP_PORT"] : 55555 - -REDIS_GOO_CACHE_HOST = ENV.include?("REDIS_GOO_CACHE_HOST") ? ENV["REDIS_GOO_CACHE_HOST"] : "localhost" -REDIS_HTTP_CACHE_HOST = ENV.include?("REDIS_HTTP_CACHE_HOST") ? ENV["REDIS_HTTP_CACHE_HOST"] : "localhost" -REDIS_PERSISTENT_HOST = ENV.include?("REDIS_PERSISTENT_HOST") ? ENV["REDIS_PERSISTENT_HOST"] : "localhost" -REDIS_PORT = ENV.include?("REDIS_PORT") ? ENV["REDIS_PORT"] : 6379 -REPORT_PATH = ENV.include?("REPORT_PATH") ? ENV["REPORT_PATH"] : "./test/ontologies_report.json" -REPOSITORY_FOLDER = ENV.include?("REPOSITORY_FOLDER") ? ENV["REPOSITORY_FOLDER"] : "./test/data/ontology_files/repo" -SOLR_PROP_SEARCH_URL = ENV.include?("SOLR_PROP_SEARCH_URL") ? ENV["SOLR_PROP_SEARCH_URL"] : "http://localhost:8983/solr" -SOLR_TERM_SEARCH_URL = ENV.include?("SOLR_TERM_SEARCH_URL") ? ENV["SOLR_TERM_SEARCH_URL"] : "http://localhost:8983/solr" +GOO_BACKEND_NAME = ENV.include?("GOO_BACKEND_NAME") ? ENV["GOO_BACKEND_NAME"] : "4store" +GOO_HOST = ENV.include?("GOO_HOST") ? ENV["GOO_HOST"] : "localhost" +GOO_PATH_DATA = ENV.include?("GOO_PATH_DATA") ? ENV["GOO_PATH_DATA"] : "/data/" +GOO_PATH_QUERY = ENV.include?("GOO_PATH_QUERY") ? ENV["GOO_PATH_QUERY"] : "/sparql/" +GOO_PATH_UPDATE = ENV.include?("GOO_PATH_UPDATE") ? ENV["GOO_PATH_UPDATE"] : "/update/" +GOO_PORT = ENV.include?("GOO_PORT") ? ENV["GOO_PORT"] : 9000 +MGREP_HOST = ENV.include?("MGREP_HOST") ? ENV["MGREP_HOST"] : "localhost" +MGREP_PORT = ENV.include?("MGREP_PORT") ? ENV["MGREP_PORT"] : 55556 +REDIS_HOST = ENV.include?("REDIS_HOST") ? ENV["REDIS_HOST"] : "localhost" +REDIS_PORT = ENV.include?("REDIS_PORT") ? ENV["REDIS_PORT"] : 6379 +SEARCH_SERVER_URL = ENV.include?('SEARCH_SERVER_URL') ? ENV['SEARCH_SERVER_URL'] : 'http://localhost:8983/solr' LinkedData.config do |config| config.goo_backend_name = GOO_BACKEND_NAME.to_s @@ -34,16 +19,15 @@ config.goo_path_query = GOO_PATH_QUERY.to_s config.goo_path_data = GOO_PATH_DATA.to_s config.goo_path_update = GOO_PATH_UPDATE.to_s - config.goo_redis_host = REDIS_GOO_CACHE_HOST.to_s + config.goo_redis_host = REDIS_HOST.to_s config.goo_redis_port = REDIS_PORT.to_i - config.http_redis_host = REDIS_HTTP_CACHE_HOST.to_s + config.http_redis_host = REDIS_HOST.to_s config.http_redis_port = REDIS_PORT.to_i - config.search_server_url = SOLR_TERM_SEARCH_URL.to_s - config.property_search_server_url = SOLR_PROP_SEARCH_URL.to_s - #config.enable_notifications = false + config.search_server_url = SEARCH_SERVER_URL.to_s + config.property_search_server_url = SEARCH_SERVER_URL.to_s # Ontology analytics - config.ontology_analytics_redis_host = REDIS_PERSISTENT_HOST.to_s + config.ontology_analytics_redis_host = REDIS_HOST.to_s config.ontology_analytics_redis_port = REDIS_PORT.to_i config.ontology_analytics_redis_field = 'test_analytics' config.oauth_providers = { @@ -67,7 +51,7 @@ end Annotator.config do |config| - config.annotator_redis_host = REDIS_PERSISTENT_HOST.to_s + config.annotator_redis_host = REDIS_HOST.to_s config.annotator_redis_port = REDIS_PORT.to_i config.mgrep_host = MGREP_HOST.to_s config.mgrep_port = MGREP_PORT.to_i @@ -75,12 +59,11 @@ end LinkedData::OntologiesAPI.config do |config| - config.http_redis_host = REDIS_HTTP_CACHE_HOST.to_s + config.http_redis_host = REDIS_HOST.to_s config.http_redis_port = REDIS_PORT.to_i end NcboCron.config do |config| - config.redis_host = REDIS_PERSISTENT_HOST.to_s + config.redis_host = REDIS_HOST.to_s config.redis_port = REDIS_PORT.to_i -# config.ontology_report_path = REPORT_PATH end diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index aa1145240..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,150 +0,0 @@ -x-app: &app - build: - context: . - args: - RUBY_VERSION: '3.2' - # Increase the version number in the image tag every time Dockerfile or its arguments is changed - image: ontologies_api:0.0.6 - environment: &env - BUNDLE_PATH: /srv/ontoportal/bundle - # default bundle config resolves to /usr/local/bundle/config inside of the container - # we are setting it to local app directory if we need to use 'bundle config local' - BUNDLE_APP_CONFIG: /srv/ontoportal/ontologies_api/.bundle - COVERAGE: 'true' - GOO_REDIS_HOST: redis-ut - REDIS_GOO_CACHE_HOST: redis-ut - REDIS_HTTP_CACHE_HOST: redis-ut - REDIS_PERSISTENT_HOST: redis-ut - REDIS_PORT: 6379 - SOLR_TERM_SEARCH_URL: http://solr-ut:8983/solr - SOLR_PROP_SEARCH_URL: http://solr-ut:8983/solr - MGREP_HOST: mgrep-ut - MGREP_PORT: 55556 - stdin_open: true - tty: true - command: "bundle exec rackup -o 0.0.0.0 --port 9393" - ports: - - 9393:9393 - volumes: - # bundle volume for hosting gems installed by bundle; it helps in local development with gem udpates - - bundle:/srv/ontoportal/bundle - # api code - - .:/srv/ontoportal/ontologies_api - # mount directory containing development version of the gems if you need to use 'bundle config local' - #- /Users/alexskr/ontoportal:/Users/alexskr/ontoportal - depends_on: &depends_on - solr-ut: - condition: service_healthy - redis-ut: - condition: service_healthy - mgrep-ut: - condition: service_healthy - -services: - api: - <<: *app - environment: - <<: *env - GOO_BACKEND_NAME: 4store - GOO_PORT: 9000 - GOO_HOST: 4store-ut - GOO_PATH_QUERY: /sparql/ - GOO_PATH_DATA: /data/ - GOO_PATH_UPDATE: /update/ - profiles: - - 4store - depends_on: - <<: *depends_on - 4store-ut: - condition: service_started - - api-agraph: - <<: *app - environment: - <<: *env - GOO_BACKEND_NAME: ag - GOO_PORT: 10035 - GOO_HOST: agraph-ut - GOO_PATH_QUERY: /repositories/ontoportal_test - GOO_PATH_DATA: /repositories/ontoportal_test/statements - GOO_PATH_UPDATE: /repositories/ontoportal_test/statements - profiles: - - agraph - depends_on: - <<: *depends_on - agraph-ut: - condition: service_healthy - - redis-ut: - image: redis - healthcheck: - test: redis-cli ping - interval: 10s - timeout: 3s - retries: 10 - - 4store-ut: - image: bde2020/4store - platform: linux/amd64 - #volume: fourstore:/var/lib/4store - command: > - bash -c "4s-backend-setup --segments 4 ontoportal_kb - && 4s-backend ontoportal_kb - && 4s-httpd -D -s-1 -p 9000 ontoportal_kb" - profiles: - - 4store - - solr-ut: - image: solr:8 - volumes: - - ./test/solr/configsets:/configsets:ro - ports: - - "8983:8983" - command: > - bash -c "precreate-core term_search_core1 /configsets/term_search - && precreate-core prop_search_core1 /configsets/property_search - && solr-foreground" - healthcheck: - test: [ "CMD-SHELL", "curl -sf http://localhost:8983/solr/term_search_core1/admin/ping?wt=json | grep -iq '\"status\":\"OK\"}' || exit 1" ] - start_period: 5s - interval: 10s - timeout: 5s - retries: 5 - - mgrep-ut: - image: ontoportal/mgrep:0.0.2 - platform: linux/amd64 - healthcheck: - test: ["CMD", "nc", "-z", "-v", "127.0.0.1", "55556"] - start_period: 3s - interval: 10s - timeout: 5s - retries: 5 - - agraph-ut: - image: franzinc/agraph:v8.3.1 - platform: linux/amd64 - environment: - - AGRAPH_SUPER_USER=test - - AGRAPH_SUPER_PASSWORD=xyzzy - shm_size: 1g - # ports: - # - 10035:10035 - command: > - bash -c "/agraph/bin/agraph-control --config /agraph/etc/agraph.cfg start - ; agtool repos create ontoportal_test - ; agtool users add anonymous - ; agtool users grant anonymous root:ontoportal_test:rw - ; tail -f /agraph/data/agraph.log" - healthcheck: - test: ["CMD-SHELL", "agtool storage-report ontoportal_test || exit 1"] - start_period: 30s - interval: 20s - timeout: 10s - retries: 10 - profiles: - - agraph - -volumes: - bundle: - diff --git a/rakelib/ontoportal_testkit.rake b/rakelib/ontoportal_testkit.rake new file mode 100644 index 000000000..7f04305c0 --- /dev/null +++ b/rakelib/ontoportal_testkit.rake @@ -0,0 +1,2 @@ +# Loads shared OntoPortal testkit rake tasks into this component. +require "ontoportal/testkit/tasks" From e55492ce65b87f0a57211486b61c798738ca780a Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Fri, 6 Mar 2026 18:38:08 -0800 Subject: [PATCH 094/173] update test config file --- config/environments/test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 2d19269bd..a24789165 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -55,7 +55,6 @@ config.annotator_redis_port = REDIS_PORT.to_i config.mgrep_host = MGREP_HOST.to_s config.mgrep_port = MGREP_PORT.to_i - config.mgrep_dictionary_file = MGREP_DICTIONARY_FILE.to_s end LinkedData::OntologiesAPI.config do |config| From 6521ffecd26303fe764c5b48c599766ce7e587fd Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Sat, 7 Mar 2026 00:42:46 -0800 Subject: [PATCH 095/173] remove TESTOPTS env var --- .github/workflows/testkit-unit-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/testkit-unit-tests.yml b/.github/workflows/testkit-unit-tests.yml index b5fe5ba83..fb5d5d98f 100644 --- a/.github/workflows/testkit-unit-tests.yml +++ b/.github/workflows/testkit-unit-tests.yml @@ -64,7 +64,6 @@ jobs: - name: Run unit tests env: CI: "true" - TESTOPTS: "-v" BACKEND: ${{ matrix.backend }} run: | MODE="${OPTK_CI_RUN_MODE:-container}" From 5e702a513d68a74b5aaf3fc5bc4187df38ee3676 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 9 Mar 2026 14:01:02 -0700 Subject: [PATCH 096/173] Gemfile.lock update --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4a43d80f8..4430c777f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 93c8ade0f7ef56fa4ad4fbdee0f9c6c4553be287 + revision: 3ef0104cd9681c6d6fa1759ae736eee4ffb0ba72 branch: ontoportal-lirmm-development specs: goo (0.0.2) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 790ac6dd95924e81bde8f6956dce3d20b3719c04 + revision: 95126578b6a62ecba0cabbbb4b8795e665810a2e branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -268,7 +268,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.18.1) + json (2.19.1) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -409,7 +409,7 @@ GEM rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.4) + redis-client (0.27.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -652,7 +652,7 @@ CHECKSUMS http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986 + json (2.19.1) sha256=dd94fdc59e48bff85913829a32350b3148156bc4fd2a95a2568a78b11344082d json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 @@ -729,7 +729,7 @@ CHECKSUMS rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae - redis-client (0.26.4) sha256=3ad70beff5da2653e02dfeae996e7d8d7147a558da12b16b2282ad345e4c7120 + redis-client (0.27.0) sha256=00e5918c1ba3fcd54b28e7be24b36fbf7b073e842c3c021ac072173c3eac42bd redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 From 93aa0c258c0655fc07601383f6c609be99867329 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 9 Mar 2026 16:48:02 -0700 Subject: [PATCH 097/173] Gemfile.lock update --- Gemfile.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4430c777f..ac8748579 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/alexskr/ontoportal_testkit.git - revision: 9944d1d5f57b11e8ae9ccda11a83c7c5b2348870 + revision: b930b550bc8c98ca566c5f71b4f91f6703721240 branch: main specs: ontoportal_testkit (0.1.0) @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: e86ece03c2d80604cdea4d96bd1de6899f6b4762 + revision: 9da3081170369e842aecef94a5bde242d85bf6db branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 + revision: ec1cfbb4f2153a00a06afc0b567cf9648e10db5a branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -55,7 +55,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 911f88f75814618f2c39d602c56d9f57245f46da + revision: 47bd7c6eb253f93d5a06266725a99bcb70688b8f branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -277,7 +277,7 @@ GEM multi_json (~> 1.15) rack (>= 2.2, < 4) rdf (~> 3.2, >= 3.2.10) - json-schema (6.1.0) + json-schema (6.2.0) addressable (~> 2.8) bigdecimal (>= 3.1, < 5) jwt (3.1.2) @@ -491,7 +491,7 @@ GEM tilt (2.7.0) time (0.4.2) date - timeout (0.6.0) + timeout (0.6.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (3.2.0) @@ -655,7 +655,7 @@ CHECKSUMS json (2.19.1) sha256=dd94fdc59e48bff85913829a32350b3148156bc4fd2a95a2568a78b11344082d json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc - json-schema (6.1.0) sha256=6bf70a2cfb6dfd5a06da28093fa8190f324c88eabd36a7f47097f227321dc702 + json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc @@ -760,7 +760,7 @@ CHECKSUMS temple (0.10.4) sha256=b7a1e94b6f09038ab0b6e4fe0126996055da2c38bec53a8a336f075748fff72c tilt (2.7.0) sha256=0d5b9ba69f6a36490c64b0eee9f6e9aad517e20dcc848800a06eb116f08c6ab3 time (0.4.2) sha256=f324e498c3bde9471d45a7d18f874c27980e9867aa5cfca61bebf52262bc3dab - timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af + timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f From 388d1bd073ee06c40003bb4fd19469617a2f3a13 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Mon, 9 Mar 2026 16:58:06 -0700 Subject: [PATCH 098/173] converted acronyms filter from Boolean to Term syntax to prevent 'too many boolean clauses' error --- Gemfile.lock | 2 +- helpers/properties_search_helper.rb | 2 +- helpers/search_helper.rb | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8a2ba0558..57d5fcb47 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,7 +58,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 790ac6dd95924e81bde8f6956dce3d20b3719c04 + revision: d89f92421a1553fc02d352fb223f63c0cc39a7d1 branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) diff --git a/helpers/properties_search_helper.rb b/helpers/properties_search_helper.rb index c3567eddd..b4597b0a9 100644 --- a/helpers/properties_search_helper.rb +++ b/helpers/properties_search_helper.rb @@ -45,7 +45,7 @@ def get_properties_search_query(text, params) onts.select! { |o| ont_type = o.ontologyType.nil? ? "ONTOLOGY" : o.ontologyType.get_code_from_id; ontology_types.include?(ont_type) } unless ontology_types.empty? acronyms = restricted_ontologies_to_acronyms(params, onts) - filter_query = get_quoted_field_query_param(acronyms, "OR", "submissionAcronym") + filter_query = get_terms_field_query_param(acronyms, "submissionAcronym") ontology_types_clause = ontology_types.empty? ? "" : get_quoted_field_query_param(ontology_types, "OR", "ontologyType") filter_query = "#{filter_query} AND #{ontology_types_clause}" unless (ontology_types_clause.empty?) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index 46e43db4f..68a21ddbe 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -157,7 +157,7 @@ def get_term_search_query(text, params={}) onts = restricted_ontologies(params) onts.select! { |o| ont_type = o.ontologyType.nil? ? "ONTOLOGY" : o.ontologyType.get_code_from_id; ontology_types.include?(ont_type) } unless ontology_types.empty? acronyms = restricted_ontologies_to_acronyms(params, onts) - filter_query = get_quoted_field_query_param(acronyms, "OR", "submissionAcronym") + filter_query = get_terms_field_query_param(acronyms, "submissionAcronym") # add subtree filter query if not empty filter_query << subtree_filter_query @@ -385,6 +385,16 @@ def get_non_quoted_field_query_param(words, fieldName="") query end + def get_terms_field_query_param(values, field_name) + return "" if values.nil? || values.empty? + + escaped_values = values.map do |value| + value.to_s.gsub('\\', '\\\\\\').gsub(',', '\\,').gsub('"', '\\"') + end + + "_query_:\"{!terms f=#{field_name}}#{escaped_values.join(',')}\"" + end + def set_page_params(params={}) pagenum, pagesize = page_params(params) params["page"] = pagenum @@ -588,4 +598,4 @@ def process_search(params = nil) end end -helpers Sinatra::Helpers::SearchHelper \ No newline at end of file +helpers Sinatra::Helpers::SearchHelper From 09dab0964dd47301478509266c9bfcdf81f4f4b3 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 9 Mar 2026 17:17:14 -0700 Subject: [PATCH 099/173] Gemfile.lock update --- Gemfile.lock | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e0cba2774..8ccc3abc9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: e86ece03c2d80604cdea4d96bd1de6899f6b4762 + revision: 9da3081170369e842aecef94a5bde242d85bf6db branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 9957238f24ad58b8f10c8011f3765bd4fbdbe4b9 + revision: ec1cfbb4f2153a00a06afc0b567cf9648e10db5a branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -55,7 +55,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 911f88f75814618f2c39d602c56d9f57245f46da + revision: 47bd7c6eb253f93d5a06266725a99bcb70688b8f branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: d6b87047562c9cd3773fcd79114d792b14fdc8c4 + revision: 95126578b6a62ecba0cabbbb4b8795e665810a2e branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -199,7 +199,6 @@ GEM ffi (1.17.3-x86-linux-musl) ffi (1.17.3-x86_64-darwin) ffi (1.17.3-x86_64-linux-gnu) - ffi (1.17.3-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -536,7 +535,6 @@ PLATFORMS x86_64-darwin x86_64-linux x86_64-linux-gnu - x86_64-linux-musl DEPENDENCIES activesupport @@ -646,7 +644,6 @@ CHECKSUMS ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f - ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba From 00a3dce07b50fa65afb45f43df34e3ed66da6c69 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 10 Mar 2026 16:19:42 -0700 Subject: [PATCH 100/173] Gemfile.lock update --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e0cba2774..15ad2c4ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 3ef0104cd9681c6d6fa1759ae736eee4ffb0ba72 + revision: f401adcae742b96a8f702314fdab1c400d714703 branch: ontoportal-lirmm-development specs: goo (0.0.2) From 6cbcea5fd04487196ceb5852f8bfaeaa332dbacc Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 10 Mar 2026 16:20:22 -0700 Subject: [PATCH 101/173] replaced another search boolean query with a term query --- helpers/search_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index 68a21ddbe..87c1e723e 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -174,7 +174,7 @@ def get_term_search_query(text, params={}) valueset_root_ids = get_valueset_root_ids(onts, params) unless valueset_root_ids.empty? - valueset_root_ids_clause = get_quoted_field_query_param(valueset_root_ids, "OR", "resource_id") + valueset_root_ids_clause = get_terms_field_query_param(valueset_root_ids, "resource_id") valueset_root_ids_clause = valueset_exclude_roots == "true" ? "AND -#{valueset_root_ids_clause}" : "AND #{valueset_root_ids_clause}" filter_query = "#{filter_query} #{valueset_root_ids_clause}" end From 52b943775e454e12c07fe84e37c1357dada52001 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Thu, 19 Mar 2026 14:12:37 -0700 Subject: [PATCH 102/173] Gemfile.lock update --- Gemfile | 4 ++-- Gemfile.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index a3abc257f..4a5279004 100644 --- a/Gemfile +++ b/Gemfile @@ -47,8 +47,8 @@ gem 'rack-contrib' gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'ontoportal-lirmm-development' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ontoportal-lirmm-goo-compat' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' diff --git a/Gemfile.lock b/Gemfile.lock index cfa0f29b2..d2ffc1a3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: f401adcae742b96a8f702314fdab1c400d714703 - branch: ontoportal-lirmm-development + revision: 2411deb0143c773b9e6d89b3232c9cca0d50e2bd + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 9da3081170369e842aecef94a5bde242d85bf6db + revision: 2b4efe17a95b5be42ead4d4507c50c244ef24e0f branch: chore/ruby3.2-minitest6-compat specs: ncbo_annotator (0.0.1) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: ec1cfbb4f2153a00a06afc0b567cf9648e10db5a + revision: f668a62b60ca6002a45779ac2afd39600ec35f00 branch: chore/ontoportal-lirmm-goo-compat specs: ncbo_cron (0.0.1) @@ -55,7 +55,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 47bd7c6eb253f93d5a06266725a99bcb70688b8f + revision: 70e49a2d3951b7d326e9ada01a4f6b9bd4df395e branch: chore/ruby3.2-minitest6-compat specs: ncbo_ontology_recommender (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 95126578b6a62ecba0cabbbb4b8795e665810a2e + revision: e7310135a510369384204d873ba8b1c5039fcdbc branch: chore/ontoportal-lirmm-goo-compat specs: ontologies_linked_data (0.0.1) @@ -88,8 +88,8 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git - revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: ontoportal-lirmm-development + revision: fa69937120104bafb3d3b8350e4f2df2efb7c247 + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From eabaf34b22140a4c02109e72c0408eb1993e3895 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Mon, 23 Mar 2026 12:58:46 -0700 Subject: [PATCH 103/173] Reset branch specified to develop --- Gemfile | 10 +++++----- Gemfile.lock | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 069ba56b6..505e06b7f 100644 --- a/Gemfile +++ b/Gemfile @@ -43,11 +43,11 @@ gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 gem 'redcarpet' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'master' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'develop' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' gem 'sparql-client', github: 'ncbo/sparql-client', tag: 'v6.3.0' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 7d7c5b123..98a197e42 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/ncbo/goo.git - revision: 5cac44e06a6bf0c093563dad66240ab07fec4d9c - branch: master + revision: 1d6b8ace1b06f7cb80fd990baf1067b88caaa5a0 + branch: develop specs: goo (0.0.2) addressable (~> 2.8) @@ -16,8 +16,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 4fb9114b80b99f0a654c7f70aaa96839c74fc615 - branch: master + revision: 55e8cbfac358b2c40deb0bd963bfe6dee91e8347 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -27,8 +27,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 7ee2651664e411945c878133073351f817ff6b8d - branch: master + revision: 4b6595f88fa367af7e99a15c475aee84210ff451 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -45,8 +45,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: c6a18eb7700b23a1a4f1e32ebc94003bf75efe93 - branch: master + revision: 76d9516adc3c5c6d5c95f21f307bdd60eb3e0acd + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -56,8 +56,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 1b47e4f1b8494dfeb864b12f8fba3879fdd783d2 - branch: master + revision: 3f042f02a069e3fe5b88dd03bcadf0774e660e4d + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -116,7 +116,7 @@ GEM ast (2.4.3) backports (3.25.1) base64 (0.3.0) - bcrypt (3.1.21) + bcrypt (3.1.22) bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) @@ -437,7 +437,7 @@ GEM tilt (2.6.1) time (0.4.2) date - timeout (0.6.0) + timeout (0.6.1) tzinfo (1.2.11) thread_safe (~> 0.1) unicode-display_width (3.1.4) From 236416ca04cc33cd4153765a40991b8e55d02c8c Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 24 Mar 2026 15:47:10 -0700 Subject: [PATCH 104/173] Ignore Claude Code local state --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 9f0468f58..45340ce35 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,9 @@ test/data/ontology_files/repo/**/* .classpath .project +# Claude Code +.claude/ + *.swp config/environments/console.rb From 5a4150435a6ea5c2916aa4980d36acd1c7644959 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 24 Mar 2026 16:03:55 -0700 Subject: [PATCH 105/173] Update Gemfile.lock --- Gemfile.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 98a197e42..cc2374a8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,7 +56,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 3f042f02a069e3fe5b88dd03bcadf0774e660e4d + revision: 89e981cb6b162108fd911e5042d9a7000dcd63be branch: develop specs: ontologies_linked_data (0.0.1) @@ -109,7 +109,7 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.8.8) + addressable (2.8.9) public_suffix (>= 2.0.2, < 8.0) airbrussh (1.5.3) sshkit (>= 1.6.1, != 1.7.0) @@ -147,7 +147,7 @@ GEM domain_name (0.6.20240107) drb (2.2.3) ed25519 (1.4.0) - faraday (2.14.0) + faraday (2.14.1) faraday-net_http (>= 2.0, < 3.5) json logger @@ -251,7 +251,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.18.0) + json (2.19.2) json-schema (2.8.1) addressable (>= 2.4) json_pure (2.8.1) @@ -274,7 +274,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0113) + mime-types-data (3.2026.0317) mini_mime (1.1.5) minitest (5.27.0) minitest-bisect (1.7.0) @@ -311,7 +311,7 @@ GEM net-ssh (7.3.0) netrc (0.11.0) newrelic_rpm (9.19.0) - oj (3.16.13) + oj (3.16.16) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -357,7 +357,7 @@ GEM redcarpet (3.6.1) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.26.4) + redis-client (0.28.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) From f36af73b9782abe2190191263f60bc0d09d3456b Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 24 Mar 2026 16:06:04 -0700 Subject: [PATCH 106/173] Gemfile.lock update --- Gemfile.lock | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d2ffc1a3a..c826e74ea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -191,12 +191,7 @@ GEM faraday (~> 2.0) ffi (1.17.3) ffi (1.17.3-aarch64-linux-gnu) - ffi (1.17.3-aarch64-linux-musl) - ffi (1.17.3-arm-linux-gnu) - ffi (1.17.3-arm-linux-musl) ffi (1.17.3-arm64-darwin) - ffi (1.17.3-x86-linux-gnu) - ffi (1.17.3-x86-linux-musl) ffi (1.17.3-x86_64-darwin) ffi (1.17.3-x86_64-linux-gnu) fugit (1.12.1) @@ -231,7 +226,6 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) - google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -257,9 +251,6 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.70.1-x86-linux) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -277,7 +268,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.19.1) + json (2.19.2) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -311,7 +302,7 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0303) + mime-types-data (3.2026.0317) mini_mime (1.1.5) minitest (6.0.2) drb (~> 2.0) @@ -418,7 +409,7 @@ GEM rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.27.0) + redis-client (0.28.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -522,18 +513,10 @@ GEM webrick (1.9.2) PLATFORMS - aarch64-linux aarch64-linux-gnu - aarch64-linux-musl - arm-linux-gnu - arm-linux-musl arm64-darwin ruby - x86-linux - x86-linux-gnu - x86-linux-musl x86_64-darwin - x86_64-linux x86_64-linux-gnu DEPENDENCIES @@ -636,12 +619,7 @@ CHECKSUMS faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 - ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 - ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 - ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f - ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089 - ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945 ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 @@ -657,7 +635,6 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c - google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -666,7 +643,6 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 - grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -676,7 +652,7 @@ CHECKSUMS http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.19.1) sha256=dd94fdc59e48bff85913829a32350b3148156bc4fd2a95a2568a78b11344082d + json (2.19.2) sha256=e7e1bd318b2c37c4ceee2444841c86539bc462e81f40d134cf97826cb14e83cf json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 @@ -692,7 +668,7 @@ CHECKSUMS mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0303) sha256=164af1de5824c5195d4b503b0a62062383b65c08671c792412450cd22d3bc224 + mime-types-data (3.2026.0317) sha256=77f078a4d8631d52b842ba77099734b06eddb7ad339d792e746d2272b67e511b mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 @@ -753,7 +729,7 @@ CHECKSUMS rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae - redis-client (0.27.0) sha256=00e5918c1ba3fcd54b28e7be24b36fbf7b073e842c3c021ac072173c3eac42bd + redis-client (0.28.0) sha256=888892f9cd8787a41c0ece00bdf5f556dfff7770326ce40bb2bc11f1bfec824b redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 From 8bbce6f1e4f48739ae049cd6dc216d7a60a82ef5 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 25 Mar 2026 11:51:01 -0700 Subject: [PATCH 107/173] change branch specifier for goo --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 4a5279004..81adae863 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,7 @@ gem 'rack-contrib' gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ontoportal-lirmm-goo-compat' diff --git a/Gemfile.lock b/Gemfile.lock index c826e74ea..97b8a1db8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 2411deb0143c773b9e6d89b3232c9cca0d50e2bd - branch: main + revision: fa850f46c94e09b6368ed47728b9cce05b7e9d54 + branch: ontoportal-lirmm-development specs: goo (0.0.2) addressable (~> 2.8) @@ -268,7 +268,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.19.2) + json (2.19.3) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -652,7 +652,7 @@ CHECKSUMS http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.19.2) sha256=e7e1bd318b2c37c4ceee2444841c86539bc462e81f40d134cf97826cb14e83cf + json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646 json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 From 47b935ad6da7ded1625e4c98c4bbcdcd0abb28b6 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Wed, 1 Apr 2026 14:37:44 -0700 Subject: [PATCH 108/173] removed legacy Solr core names and updated to the new collection names --- test/controllers/test_search_models_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index 9b7ab3a60..c065e1779 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -18,7 +18,7 @@ def test_show_all_collection get '/admin/search/collections' assert last_response.ok? res = MultiJson.load(last_response.body) - required = %w[ontology_data ontology_metadata prop_search_core1 term_search_core1] + required = %w[ontology_data ontology_metadata property_search term_search] allowed_extra = %w[term_search test_solr] collections = res["collections"] assert_empty required - collections From d14a2b55ea73b87a29a33d123b72883d1cf2b770 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Wed, 1 Apr 2026 14:41:35 -0700 Subject: [PATCH 109/173] Gemfile.lock update --- Gemfile | 8 ++++---- Gemfile.lock | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index 81adae863..7404689b3 100644 --- a/Gemfile +++ b/Gemfile @@ -47,12 +47,12 @@ gem 'rack-contrib' gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'ontoportal-lirmm-development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'goo', github: 'ncbo/goo', branch: 'development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ontoportal-lirmm-goo-compat' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 97b8a1db8..56fd1ebab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git revision: fa850f46c94e09b6368ed47728b9cce05b7e9d54 - branch: ontoportal-lirmm-development + branch: development specs: goo (0.0.2) addressable (~> 2.8) @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: f668a62b60ca6002a45779ac2afd39600ec35f00 - branch: chore/ontoportal-lirmm-goo-compat + revision: 102e0f8f10dcbfbc50301764d84259e5aca2c7b2 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: e7310135a510369384204d873ba8b1c5039fcdbc - branch: chore/ontoportal-lirmm-goo-compat + revision: a4bbd57fcaa78fa66a11b494384b1791b6e9a6d8 + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -88,8 +88,8 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git - revision: fa69937120104bafb3d3b8350e4f2df2efb7c247 - branch: main + revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From 2299c7d48d94cbdf715e422e9e5e0a0ef642c9b2 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Wed, 1 Apr 2026 15:01:03 -0700 Subject: [PATCH 110/173] Gemfile and Gemfile.lock updates --- Gemfile | 4 ++-- Gemfile.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 7404689b3..6b04d1a13 100644 --- a/Gemfile +++ b/Gemfile @@ -49,9 +49,9 @@ gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) gem 'goo', github: 'ncbo/goo', branch: 'development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 56fd1ebab..afd934022 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 2b4efe17a95b5be42ead4d4507c50c244ef24e0f - branch: chore/ruby3.2-minitest6-compat + revision: 7755a51ce891763a0ba174813796df116abca8a9 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 70e49a2d3951b7d326e9ada01a4f6b9bd4df395e - branch: chore/ruby3.2-minitest6-compat + revision: 2cce61a8e0db96fed9a2a8c4c5b585c385cd8a2c + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo From 58b9413bdbdce47c36584abf88958b2f458cc3fe Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Wed, 1 Apr 2026 15:40:59 -0700 Subject: [PATCH 111/173] Gemfile and Gemfile.lock updates --- Gemfile | 12 ++++++------ Gemfile.lock | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 4a5279004..f2f5a2f81 100644 --- a/Gemfile +++ b/Gemfile @@ -47,12 +47,12 @@ gem 'rack-contrib' gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'chore/ontoportal-lirmm-goo-compat' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'chore/ruby3.2-minitest6-compat' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'chore/ontoportal-lirmm-goo-compat' +gem 'goo', github: 'ncbo/goo', branch: 'feature/solrcloud-alias-indexing-codex' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'feature/solrcloud-alias-indexing-codex' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'feature/solrcloud-alias-indexing-codex' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index d2ffc1a3a..291151b7e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 2411deb0143c773b9e6d89b3232c9cca0d50e2bd - branch: main + revision: 2cd237f26202649e4d5cc569aac6272b8448858c + branch: feature/solrcloud-alias-indexing-codex specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 2b4efe17a95b5be42ead4d4507c50c244ef24e0f - branch: chore/ruby3.2-minitest6-compat + revision: 7755a51ce891763a0ba174813796df116abca8a9 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: f668a62b60ca6002a45779ac2afd39600ec35f00 - branch: chore/ontoportal-lirmm-goo-compat + revision: cba1e427240f3909789f263f2105a35f50423176 + branch: feature/solrcloud-alias-indexing-codex specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 70e49a2d3951b7d326e9ada01a4f6b9bd4df395e - branch: chore/ruby3.2-minitest6-compat + revision: 2cce61a8e0db96fed9a2a8c4c5b585c385cd8a2c + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: e7310135a510369384204d873ba8b1c5039fcdbc - branch: chore/ontoportal-lirmm-goo-compat + revision: 8d5090aeeb78d6cd2bf5133ff926d0c1bac44f94 + branch: feature/solrcloud-alias-indexing-codex specs: ontologies_linked_data (0.0.1) activesupport @@ -88,8 +88,8 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git - revision: fa69937120104bafb3d3b8350e4f2df2efb7c247 - branch: main + revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From cf6e61f3fcfcfdf515f31873a8734cbf016fb6e3 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 14 Apr 2026 17:21:13 -0700 Subject: [PATCH 112/173] Enforce slice-based access control on individual ontology endpoints Previously, slice filtering only applied to collection responses (GET /ontologies) because filter_for_slice checked obj.is_a?(Enumerable). Single ontology access (GET /ontologies/:acronym) and all sub-routes (submissions, classes, etc.) bypassed slice enforcement entirely. Add a Sinatra before filter on /ontologies/:acronym routes that checks slice membership and returns 404 for ontologies not in the current slice. Also memoize slice lookups per request to avoid duplicate triplestore queries. --- controllers/application_controller.rb | 9 +++++-- helpers/slices_helper.rb | 20 ++++++++++++-- test/helpers/test_slices_helper.rb | 38 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/controllers/application_controller.rb b/controllers/application_controller.rb index 5693f8c16..d3117a0ca 100644 --- a/controllers/application_controller.rb +++ b/controllers/application_controller.rb @@ -5,8 +5,13 @@ class ApplicationController extend Sinatra::Delegator # Run before route - before { - } + before %r{/ontologies/([^/]+).*} do |acronym| + if LinkedData.settings.enable_slices && request.get? + unless ontology_in_slice?(acronym) + error 404, "Ontology not found" + end + end + end # Run after route after { diff --git a/helpers/slices_helper.rb b/helpers/slices_helper.rb index d862073fe..ebd21e824 100644 --- a/helpers/slices_helper.rb +++ b/helpers/slices_helper.rb @@ -18,12 +18,28 @@ def filter_for_slice(obj) obj.select { |o| slice.ontology_id_set.include?(o.id.to_s) } end + def ontology_in_slice?(acronym) + return true unless LinkedData.settings.enable_slices + return true unless slice_request? + + slice = current_slice + return true unless slice + + ont_id = (LinkedData::Models::Ontology.id_prefix + acronym).to_s + slice.ontology_id_set.include?(ont_id) + end + def slice_request? - env['ncbo.slice'] && !LinkedData::Models::Slice.find(env['ncbo.slice']).first.nil? + return env['ncbo.slice.is_request'] if env.key?('ncbo.slice.is_request') + + env['ncbo.slice.is_request'] = !!(env['ncbo.slice'] && current_slice) end def current_slice - LinkedData::Models::Slice.find(env['ncbo.slice']).include(LinkedData::Models::Slice.attributes).first + return env['ncbo.slice.object'] if env.key?('ncbo.slice.object') + + env['ncbo.slice.object'] = LinkedData::Models::Slice.find(env['ncbo.slice']) + .include(LinkedData::Models::Slice.attributes).first end def current_slice_acronyms diff --git a/test/helpers/test_slices_helper.rb b/test/helpers/test_slices_helper.rb index 33ed36abd..92f051c91 100644 --- a/test/helpers/test_slices_helper.rb +++ b/test/helpers/test_slices_helper.rb @@ -29,6 +29,9 @@ def before_suite @@group.bring(:ontologies) + # TODO: This test uses @@group_acronym as the slice identifier throughout. Consider + # introducing a @@slice_acronym variable to better reflect that slices and groups are + # distinct concepts — not all groups become slices (only those with ontologies). LinkedData::Models::Slice.synchronize_groups_to_slices end @@ -76,6 +79,41 @@ def test_search_slices assert results.all? {|r| group_ids.include?(r["links"]["ontology"])} end + def test_single_ontology_in_slice_returns_200 + ont = @@onts[0] + ont.bring(:acronym) + get "http://#{@@group_acronym}.dev/ontologies/#{ont.acronym}" + assert last_response.ok?, "Expected 200 for ontology in slice, got #{last_response.status}" + end + + def test_single_ontology_not_in_slice_returns_404 + ont = @@onts[3] + ont.bring(:acronym) + get "http://#{@@group_acronym}.dev/ontologies/#{ont.acronym}" + assert_equal 404, last_response.status + end + + def test_single_ontology_not_in_slice_via_header_returns_404 + ont = @@onts[3] + ont.bring(:acronym) + get "/ontologies/#{ont.acronym}", {}, "HTTP_NCBO_SLICE" => @@group_acronym + assert_equal 404, last_response.status + end + + def test_single_ontology_without_slice_returns_200 + ont = @@onts[3] + ont.bring(:acronym) + get "/ontologies/#{ont.acronym}" + assert last_response.ok?, "Expected 200 without slice context, got #{last_response.status}" + end + + def test_ontology_sub_route_not_in_slice_returns_404 + ont = @@onts[3] + ont.bring(:acronym) + get "http://#{@@group_acronym}.dev/ontologies/#{ont.acronym}/submissions" + assert_equal 404, last_response.status + end + def test_mappings_slices LinkedData::Mappings.create_mapping_counts(Logger.new(TestLogFile.new)) From 46f8f0866f07ec07ad69ff3cfe0653806f14f9c4 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 20 Apr 2026 19:20:26 -0700 Subject: [PATCH 113/173] Add run_metrics to test setup for classes and recommender tests After removing the metrics.csv fallback from class_count in ncbo/ontologies_linked_data#277, tests that don't compute metrics now fail because class_count returns -1 without a Metric object in the triplestore. --- Gemfile.lock | 75 ++++++++++--------- test/controllers/test_classes_controller.rb | 2 +- .../test_recommender_controller.rb | 3 +- 3 files changed, 41 insertions(+), 39 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index afd934022..09dba4fec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: a4bbd57fcaa78fa66a11b494384b1791b6e9a6d8 + revision: 7932bf41d442f3a2c0d589e0c14fbf2e4917d08a branch: develop specs: ontologies_linked_data (0.0.1) @@ -124,7 +124,7 @@ GIT GEM remote: https://rubygems.org/ specs: - activesupport (8.1.2) + activesupport (8.1.3) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -137,7 +137,7 @@ GEM securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) - addressable (2.8.9) + addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) airbrussh (1.6.1) sshkit (>= 1.6.1, != 1.7.0) @@ -145,11 +145,11 @@ GEM ast (2.4.3) base64 (0.3.0) bcp47_spec (0.2.1) - bcrypt (3.1.21) + bcrypt (3.1.22) bcrypt_pbkdf (1.1.2) bcrypt_pbkdf (1.1.2-arm64-darwin) bcrypt_pbkdf (1.1.2-x86_64-darwin) - bigdecimal (4.0.1) + bigdecimal (4.1.2) builder (3.3.0) byebug (12.0.0) capistrano (3.20.0) @@ -173,8 +173,9 @@ GEM date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) - down (5.4.2) + down (5.5.0) addressable (~> 2.8) + base64 (~> 0.3) drb (2.2.3) ed25519 (1.4.0) et-orbi (1.4.0) @@ -189,11 +190,11 @@ GEM net-http (~> 0.5) faraday-retry (2.4.0) faraday (~> 2.0) - ffi (1.17.3) - ffi (1.17.3-aarch64-linux-gnu) - ffi (1.17.3-arm64-darwin) - ffi (1.17.3-x86_64-darwin) - ffi (1.17.3-x86_64-linux-gnu) + ffi (1.17.4) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -263,12 +264,12 @@ GEM hashdiff (1.2.1) htmlentities (4.4.2) http-accept (1.7.0) - http-cookie (1.1.0) + http-cookie (1.1.6) domain_name (~> 0.5) i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.19.3) + json (2.19.4) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -284,7 +285,7 @@ GEM base64 kgio (2.11.4) language_server-protocol (3.17.0.5) - libxml-ruby (5.0.5) + libxml-ruby (6.0.0) link_header (0.0.8) lint_roller (1.1.0) logger (1.7.0) @@ -302,9 +303,9 @@ GEM mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0317) + mime-types-data (3.2026.0414) mini_mime (1.1.5) - minitest (6.0.2) + minitest (6.0.5) drb (~> 2.0) prism (~> 1.5) minitest-hooks (1.5.3) @@ -317,7 +318,7 @@ GEM minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis - multi_json (1.19.1) + multi_json (1.20.1) mustermann (3.0.4) ruby2_keywords (~> 0.0.1) net-ftp (0.3.9) @@ -342,7 +343,7 @@ GEM net-protocol net-ssh (7.3.0) netrc (0.11.0) - oj (3.16.15) + oj (3.17.0) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -365,7 +366,7 @@ GEM public_suffix (7.0.5) raabro (1.4.0) racc (1.8.1) - rack (3.2.5) + rack (3.2.6) rack-accept (0.4.5) rack (>= 0.4) rack-attack (6.8.0) @@ -583,18 +584,18 @@ DEPENDENCIES webrick CHECKSUMS - activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae - addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485 + activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e + addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af airbrussh (1.6.1) sha256=9a5fc95583cefe722054a016d26ff0338cf00072b031b829086dde2039d5836a ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b bcp47_spec (0.2.1) sha256=3fd62edf96c126bd9624e4319ac74082a966081859d1ee0ef3c3041640a37810 - bcrypt (3.1.21) sha256=5964613d750a42c7ee5dc61f7b9336fb6caca429ba4ac9f2011609946e4a2dcf + bcrypt (3.1.22) sha256=1f0072e88c2d705d94aff7f2c5cb02eb3f1ec4b8368671e19112527489f29032 bcrypt_pbkdf (1.1.2) sha256=c2414c23ce66869b3eb9f643d6a3374d8322dfb5078125c82792304c10b94cf6 bcrypt_pbkdf (1.1.2-arm64-darwin) sha256=afdd6feb6ed5a97b8e44caacb3f2d641b98af78e6a516d4a3520b69af5cf9fea bcrypt_pbkdf (1.1.2-x86_64-darwin) sha256=35f5639d0058e6c2cc2f856f9c0b14080543268d3047abe6bc81c513093caa0e - bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e capistrano (3.20.0) sha256=0113e58dda99add0342e56a244f664734c59f442c5ed734f5303b0b559b479c9 @@ -609,7 +610,7 @@ CHECKSUMS date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - down (5.4.2) sha256=516e5e01e7a96214a7e2cd155aac6f700593038ae6c857c0f4a05413b1c58acf + down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc @@ -617,11 +618,11 @@ CHECKSUMS faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe - ffi (1.17.3) sha256=0e9f39f7bb3934f77ad6feab49662be77e87eedcdeb2a3f5c0234c2938563d4c - ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 - ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f - ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 - ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f + ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf + ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 + ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -649,17 +650,17 @@ CHECKSUMS hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 htmlentities (4.4.2) sha256=bbafbdf69f2eca9262be4efef7e43e6a1de54c95eb600f26984f71d2fe96c5c3 http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 - http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 + http-cookie (1.1.6) sha256=ba4b82be64de61dc281243dac70e3c382c45142f20268ed9276a3670c93feaa9 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646 + json (2.19.4) sha256=670a7d333fb3b18ca5b29cb255eb7bef099e40d88c02c80bd42a3f30fe5239ac json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc - libxml-ruby (5.0.5) sha256=f1bc07152982df555d70159a694ee2a53539de2cdad4b3c8a447fbb15e7e4e9a + libxml-ruby (6.0.0) sha256=a9d9458d018dee591d0995fdc1110cd67ec32b7be67d36fdb9e0b01a4ca9dac4 link_header (0.0.8) sha256=15c65ce43b29f739b30d05e5f25c22c23797e89cf6f905dbb595fb4c70cb55f9 lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 @@ -668,14 +669,14 @@ CHECKSUMS mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0317) sha256=77f078a4d8631d52b842ba77099734b06eddb7ad339d792e746d2272b67e511b + mime-types-data (3.2026.0414) sha256=461c4c655373a44bd6c5fe54bcf5b7776026ea96e808144b1ec465c4b99148cc mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef - minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d + minitest (6.0.5) sha256=f007d7246bf4feea549502842cd7c6aba8851cdc9c90ba06de9c476c0d01155c minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 - multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 + multi_json (1.20.1) sha256=2f3934e805cc45ef91b551a1f89d0e9191abd06a5e04a2ef09a6a036c452ca6d mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22 ncbo_annotator (0.0.1) ncbo_cron (0.0.1) @@ -691,7 +692,7 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f - oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd + oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) ontoportal_testkit (0.1.0) @@ -707,7 +708,7 @@ CHECKSUMS public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f - rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3 + rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2 rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2 rack-cache (1.17.0) sha256=49592f3ef2173b0f5524df98bb801fb411e839869e7ce84ac428dc492bf0eb90 diff --git a/test/controllers/test_classes_controller.rb b/test/controllers/test_classes_controller.rb index bee4d4bed..93ac060a2 100644 --- a/test/controllers/test_classes_controller.rb +++ b/test/controllers/test_classes_controller.rb @@ -8,7 +8,7 @@ def before_suite submissions_to_process: [1, 2], process_submission: true, random_submission_count: false, - process_options: {process_rdf: true, extract_metadata: false} + process_options: {process_rdf: true, extract_metadata: false, run_metrics: true} } return LinkedData::SampleData::Ontology.create_ontologies_and_submissions(options) end diff --git a/test/controllers/test_recommender_controller.rb b/test/controllers/test_recommender_controller.rb index c46255fc3..1497bdb90 100644 --- a/test/controllers/test_recommender_controller.rb +++ b/test/controllers/test_recommender_controller.rb @@ -14,7 +14,8 @@ def before_suite @@redis.del(mappings) end LinkedData::SampleData::Ontology.delete_ontologies_and_submissions - @@ontologies = LinkedData::SampleData::Ontology.sample_owl_ontologies(process_submission: true) + @@ontologies = LinkedData::SampleData::Ontology.sample_owl_ontologies(process_submission: true, + process_options: {process_rdf: true, extract_metadata: false, run_metrics: true}) annotator = Annotator::Models::NcboAnnotator.new annotator.init_redis_for_tests() annotator.create_term_cache_from_ontologies(@@ontologies, false) From 2dd991a1b073eb0f039443e827b177b802cf3987 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 20 Apr 2026 20:45:04 -0700 Subject: [PATCH 114/173] update ontoportal testkit --- .github/workflows/testkit-unit-tests.yml | 8 ++++---- Gemfile.lock | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/testkit-unit-tests.yml b/.github/workflows/testkit-unit-tests.yml index 358194a41..7ccb9bcae 100644 --- a/.github/workflows/testkit-unit-tests.yml +++ b/.github/workflows/testkit-unit-tests.yml @@ -22,7 +22,7 @@ jobs: outputs: backends: ${{ steps.cfg.outputs.backends }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - id: cfg name: Read backend matrix from .ontoportal-testkit.yml @@ -40,7 +40,7 @@ jobs: backend: ${{ fromJson(needs.prepare.outputs.backends) }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Ruby from .ruby-version uses: ruby/setup-ruby@v1 @@ -50,7 +50,7 @@ jobs: - name: Set up Java 11 (native mode) if: env.OPTK_CI_RUN_MODE == 'native' - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '11' @@ -79,7 +79,7 @@ jobs: bundle exec rake "$TASK" - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unittests,${{ matrix.backend }} diff --git a/Gemfile.lock b/Gemfile.lock index 09dba4fec..ae551f8bb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/alexskr/ontoportal_testkit.git - revision: b930b550bc8c98ca566c5f71b4f91f6703721240 + revision: 4e86e455af6a9d515a54d9d82cbecf2e7cac34e8 branch: main specs: ontoportal_testkit (0.1.0) @@ -394,7 +394,7 @@ GEM rack (>= 3) rainbow (3.1.1) raindrops (0.20.1) - rake (13.3.1) + rake (13.4.2) rdf (3.3.1) bcp47_spec (~> 0.2) link_header (~> 0.0, >= 0.0.8) @@ -723,7 +723,7 @@ CHECKSUMS rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a raindrops (0.20.1) sha256=aa0eb9ff6834f2d9e232ba688bd49cb30be893bc5a3452e74722c94c1fab4730 - rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 rdf (3.3.1) sha256=dda6a2c95198915fc63d66ee270e35d4a76d431720747a2cf97ecd92062fa150 rdf-raptor (3.3.0) rdf-rdfxml (3.3.0) sha256=11647f6111b97b6a9b82413bd9810d4bb5524aa7dd06b3c1330bf58ec3aa6a9a From f83aeac0d1a7b845b4ccf926b8ae73568ab522b1 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 20 Apr 2026 22:03:07 -0700 Subject: [PATCH 115/173] Gemfile.lock update --- Gemfile.lock | 69 +++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ae551f8bb..61cfe6223 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/alexskr/ontoportal_testkit.git - revision: 4e86e455af6a9d515a54d9d82cbecf2e7cac34e8 + revision: 5e65844246008127231880edc6a2e72ab09a5fb7 branch: main specs: ontoportal_testkit (0.1.0) @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 7755a51ce891763a0ba174813796df116abca8a9 + revision: 3e9c060baa3505af13671b06b3724524277fa301 branch: develop specs: ncbo_annotator (0.0.1) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 102e0f8f10dcbfbc50301764d84259e5aca2c7b2 + revision: a4768dd3e85ab853765a6825760fc950f72b9ae4 branch: develop specs: ncbo_cron (0.0.1) @@ -141,7 +141,7 @@ GEM public_suffix (>= 2.0.2, < 8.0) airbrussh (1.6.1) sshkit (>= 1.6.1, != 1.7.0) - ansi (1.5.0) + ansi (1.6.0) ast (2.4.3) base64 (0.3.0) bcp47_spec (0.2.1) @@ -210,7 +210,7 @@ GEM grpc (~> 1.66) get_process_mem (0.2.7) ffi (~> 1.0) - google-analytics-data (0.7.2) + google-analytics-data (0.8.0) google-analytics-data-v1beta (>= 0.11, < 2.a) google-cloud-core (~> 1.6) google-analytics-data-v1beta (0.17.0) @@ -222,7 +222,7 @@ GEM google-cloud-env (2.3.1) base64 (~> 0.2) faraday (>= 1.0, < 3.a) - google-cloud-errors (1.5.0) + google-cloud-errors (1.6.0) google-logging-utils (0.2.0) google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) @@ -297,8 +297,6 @@ GEM net-imap net-pop net-smtp - mcp (0.8.0) - json-schema (>= 4.1) method_source (1.1.0) mime-types (3.7.0) logger @@ -310,17 +308,16 @@ GEM prism (~> 1.5) minitest-hooks (1.5.3) minitest (> 5.3) - minitest-reporters (1.7.1) + minitest-reporters (1.8.0) ansi builder - minitest (>= 5.0) + minitest (>= 5.0, < 7) ruby-progressbar minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis multi_json (1.20.1) - mustermann (3.0.4) - ruby2_keywords (~> 0.0.1) + mustermann (3.1.1) net-ftp (0.3.9) net-protocol time @@ -341,7 +338,7 @@ GEM net-ssh (>= 5.0.0, < 8.0.0) net-smtp (0.5.1) net-protocol - net-ssh (7.3.0) + net-ssh (7.3.2) netrc (0.11.0) oj (3.17.0) bigdecimal (>= 3.0) @@ -351,9 +348,9 @@ GEM os (1.1.4) ostruct (0.6.3) pandoc-ruby (2.1.10) - parallel (1.27.0) + parallel (1.28.0) parseconfig (1.1.2) - parser (3.3.10.2) + parser (3.3.11.1) ast (~> 2.4.1) racc pony (1.13.1) @@ -384,7 +381,7 @@ GEM base64 (>= 0.1.0) logger (>= 1.6.0) rack (>= 3.0.0, < 4) - rack-session (2.1.1) + rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) @@ -417,7 +414,7 @@ GEM redis-store (>= 1.6, < 2) redis-store (1.11.0) redis (>= 4, < 6) - regexp_parser (2.11.3) + regexp_parser (2.12.0) reline (0.6.3) io-console (~> 0.5) request_store (1.7.0) @@ -431,24 +428,22 @@ GEM rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) - rubocop (1.85.1) + rubocop (1.86.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) - mcp (~> 0.6) - parallel (~> 1.10) + parallel (>= 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.49.0) + rubocop-ast (1.49.1) parser (>= 3.3.7.2) prism (~> 1.7) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - ruby2_keywords (0.0.5) rubyzip (3.2.2) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) @@ -507,7 +502,7 @@ GEM uri (1.1.1) uuid (2.3.9) macaddr (~> 1.0) - webmock (3.26.1) + webmock (3.26.2) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -587,7 +582,7 @@ CHECKSUMS activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af airbrussh (1.6.1) sha256=9a5fc95583cefe722054a016d26ff0338cf00072b031b829086dde2039d5836a - ansi (1.5.0) sha256=5408253274e33d9d27d4a98c46d2998266fd51cba58a7eb9d08f50e57ed23592 + ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b bcp47_spec (0.2.1) sha256=3fd62edf96c126bd9624e4319ac74082a966081859d1ee0ef3c3041640a37810 @@ -627,11 +622,11 @@ CHECKSUMS gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba goo (0.0.2) - google-analytics-data (0.7.2) sha256=5e4bf6dc575c7725c2b32541725749890a88e0a64ff0ad7e8a73f75ad5a1bbc9 + google-analytics-data (0.8.0) sha256=8f2cd51aca51b6f4764c33e3cdc9862892ae4ab6ef456b111bcc35a319d2b242 google-analytics-data-v1beta (0.17.0) sha256=1145d30d794bcf6bf8b723140a0ee2c445e740b82cf4051a31d992e7393168a6 google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7 - google-cloud-errors (1.5.0) sha256=b56be28b8c10628125214dde571b925cfcebdbc58619e598250c37a2114f7b4b + google-cloud-errors (1.6.0) sha256=1da8476dd706ad04b9d32e3c4b90d07d3463b37d6407cb56d41342ea7647d0a1 google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 @@ -666,18 +661,17 @@ CHECKSUMS logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 macaddr (1.7.2) sha256=da377809968bbc1160bf02a999e916bb3255000007291d9d1a49a93ceedadf82 mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 - mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 mime-types-data (3.2026.0414) sha256=461c4c655373a44bd6c5fe54bcf5b7776026ea96e808144b1ec465c4b99148cc mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef minitest (6.0.5) sha256=f007d7246bf4feea549502842cd7c6aba8851cdc9c90ba06de9c476c0d01155c minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 - minitest-reporters (1.7.1) sha256=5060413a0c95b8c32fe73e0606f3631c173a884d7900e50013e15094eb50562c + minitest-reporters (1.8.0) sha256=8ce5280fb73ad3178ae525454df169b6f28c1b38b1d088ea91815d3a370ba384 minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 multi_json (1.20.1) sha256=2f3934e805cc45ef91b551a1f89d0e9191abd06a5e04a2ef09a6a036c452ca6d - mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22 + mustermann (3.1.1) sha256=4c6170c7234d5499c345562ba7c7dfe73e1754286dcc1abb053064d66a127198 ncbo_annotator (0.0.1) ncbo_cron (0.0.1) ncbo_ontology_recommender (0.0.1) @@ -690,7 +684,7 @@ CHECKSUMS net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d net-sftp (4.0.0) sha256=65bb91c859c2f93b09826757af11b69af931a3a9155050f50d1b06d384526364 net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 - net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 + net-ssh (7.3.2) sha256=65029e213c380e20e5fd92ece663934ab0a0fe888e0cd7cc6a5b664074362dd4 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e @@ -699,9 +693,9 @@ CHECKSUMS os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 - parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parallel (1.28.0) sha256=33e6de1484baf2524792d178b0913fc8eb94c628d6cfe45599ad4458c638c970 parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 - parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357 + parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 pony (1.13.1) sha256=ab507c8ade8b35de96f1e75c0ae4566a3c40ac8a0d5101433969b6fd29c718a7 prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e @@ -717,7 +711,7 @@ CHECKSUMS rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78 rack-post-body-to-params (0.1.8) rack-protection (4.2.1) sha256=cf6e2842df8c55f5e4d1a4be015e603e19e9bc3a7178bae58949ccbb58558bac - rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 + rack-session (2.1.2) sha256=595434f8c0c3473ae7d7ac56ecda6cc6dfd9d37c0b2b5255330aa1576967ffe8 rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9 rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 @@ -733,17 +727,16 @@ CHECKSUMS redis-client (0.28.0) sha256=888892f9cd8787a41c0ece00bdf5f556dfff7770326ce40bb2bc11f1bfec824b redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 - regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b - rubocop (1.85.1) sha256=3dbcf9e961baa4c376eeeb2a03913dca5e3987033b04d38fa538aa1e7406cc77 - rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + rubocop (1.86.1) sha256=44415f3f01d01a21e01132248d2fd0867572475b566ca188a0a42133a08d4531 + rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 - ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 @@ -769,7 +762,7 @@ CHECKSUMS unicorn-worker-killer (0.4.5) sha256=fc3c5dae71566c9e2a165dfbf75664f7bc16fec20251a1d09c3375ffe58b3991 uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 uuid (2.3.9) sha256=aec0cf592053cd6e07c13c1ef94c440aba705f22eb1ee767b39631f2760124d7 - webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 + webmock (3.26.2) sha256=774556f2ea6371846cca68c01769b2eac0d134492d21f6d0ab5dd643965a4c90 webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH From 7ca4a76e30c726db5be71e979c00d6911bc6040d Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 20 Apr 2026 22:28:53 -0700 Subject: [PATCH 116/173] ontoportal testkit update --- Gemfile.lock | 2 +- rakelib/ontoportal_testkit.rake | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 61cfe6223..fd6764fe9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/alexskr/ontoportal_testkit.git - revision: 5e65844246008127231880edc6a2e72ab09a5fb7 + revision: 33f52810bdb576c25922fb739dea49507cf362a6 branch: main specs: ontoportal_testkit (0.1.0) diff --git a/rakelib/ontoportal_testkit.rake b/rakelib/ontoportal_testkit.rake index 39a3ec73d..324002534 100644 --- a/rakelib/ontoportal_testkit.rake +++ b/rakelib/ontoportal_testkit.rake @@ -1 +1,8 @@ -require "ontoportal/testkit/tasks" +begin + require "ontoportal/testkit/tasks" +rescue LoadError + # ontoportal_testkit lives in group :test. Deploy/prod bundles built with + # BUNDLE_WITHOUT=test (and Capistrano prod hosts) don't include it, so the + # require would fail and Rake would abort before any other task could run. + # Skip silently — testkit tasks are intentionally unavailable outside dev/test. +end From 22c7b9e9871b4eb23e44172ad5bfedc3b413d73c Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 21 Apr 2026 14:12:48 -0700 Subject: [PATCH 117/173] Gemfile.lock update --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index fd6764fe9..bbce33202 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 3e9c060baa3505af13671b06b3724524277fa301 + revision: 5243ea8db4302ca756c66bf50233e88606830326 branch: develop specs: ncbo_annotator (0.0.1) @@ -55,7 +55,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 2cce61a8e0db96fed9a2a8c4c5b585c385cd8a2c + revision: fa30fe29838cc40377e05c663ca50ef260071e93 branch: develop specs: ncbo_ontology_recommender (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 7932bf41d442f3a2c0d589e0c14fbf2e4917d08a + revision: 4a02edaafa0ceab608b66b919d0d13cf3b280c13 branch: develop specs: ontologies_linked_data (0.0.1) From ad51191ed905a66777c26ddab7b0b57c880f4930 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 21 Apr 2026 14:27:56 -0700 Subject: [PATCH 118/173] Gemfile.lock update --- Gemfile.lock | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index bbce33202..25fed09c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -192,9 +192,15 @@ GEM faraday (~> 2.0) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -227,6 +233,7 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -252,6 +259,9 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -509,11 +519,20 @@ GEM webrick (1.9.2) PLATFORMS + aarch64-linux aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl arm64-darwin ruby + x86-linux + x86-linux-gnu + x86-linux-musl x86_64-darwin + x86_64-linux x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES activesupport @@ -615,9 +634,15 @@ CHECKSUMS faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 + ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 + ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf + ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d + ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -631,6 +656,7 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c + google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -639,6 +665,7 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 + grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c From 9441f4184000004834003d4c516e7173aa9bb40e Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 21 Apr 2026 14:31:21 -0700 Subject: [PATCH 119/173] Gemfile & Gemfile.lock update --- Gemfile | 12 ++++++------ Gemfile.lock | 37 ++++++++++++++----------------------- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/Gemfile b/Gemfile index 6b04d1a13..986deb641 100644 --- a/Gemfile +++ b/Gemfile @@ -47,12 +47,12 @@ gem 'rack-contrib' gem 'pandoc-ruby' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 25fed09c3..8e3488598 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git revision: fa850f46c94e09b6368ed47728b9cce05b7e9d54 - branch: development + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 5243ea8db4302ca756c66bf50233e88606830326 - branch: develop + revision: b216bdde2de471fc0f851556ffa2327333516e79 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: a4768dd3e85ab853765a6825760fc950f72b9ae4 - branch: develop + revision: 043a43cc5b484a98c856c48a55cd1746c570a74d + branch: master specs: ncbo_cron (0.0.1) dante @@ -51,12 +51,12 @@ GIT ncbo_annotator ontologies_linked_data redis - rufus-scheduler (~> 3.9) + rufus-scheduler (~> 2.0.24) GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: fa30fe29838cc40377e05c663ca50ef260071e93 - branch: develop + revision: ddf6e3b207417e694727c2be3e0431687b1758d0 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 4a02edaafa0ceab608b66b919d0d13cf3b280c13 - branch: develop + revision: fb7a292c7a97b9d19e359e20fe93c46131850d18 + branch: master specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: development + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) @@ -178,8 +178,6 @@ GEM base64 (~> 0.3) drb (2.2.3) ed25519 (1.4.0) - et-orbi (1.4.0) - tzinfo faraday (2.14.1) faraday-net_http (>= 2.0, < 3.5) json @@ -201,9 +199,6 @@ GEM ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) ffi (1.17.4-x86_64-linux-musl) - fugit (1.12.1) - et-orbi (~> 1.4) - raabro (~> 1.4) gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) @@ -371,7 +366,6 @@ GEM method_source (~> 1.0) reline (>= 0.6.0) public_suffix (7.0.5) - raabro (1.4.0) racc (1.8.1) rack (3.2.6) rack-accept (0.4.5) @@ -455,8 +449,8 @@ GEM ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) rubyzip (3.2.2) - rufus-scheduler (3.9.2) - fugit (~> 1.1, >= 1.11.1) + rufus-scheduler (2.0.24) + tzinfo (>= 0.3.22) securerandom (0.4.1) signet (0.21.0) addressable (~> 2.8) @@ -627,7 +621,6 @@ CHECKSUMS down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 - et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c @@ -643,7 +636,6 @@ CHECKSUMS ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e - fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba goo (0.0.2) @@ -727,7 +719,6 @@ CHECKSUMS prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 - raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2 rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 @@ -765,7 +756,7 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c - rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 + rufus-scheduler (2.0.24) sha256=cf1b6ebe4835368d48e5ec9fd275327ffb03fc566fd1609744b76749b32ad446 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 shotgun (0.9.2) signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b From 3ff50f7ba630c6ad2cce977477963dbfbe8e1e89 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 21 Apr 2026 19:52:49 -0700 Subject: [PATCH 120/173] Use id_from_unique_attribute for slice ontology ID lookup Canonicalize ontology ID construction in ontology_in_slice? to match how slice.ontology_id_set entries are generated by Goo, avoiding silent comparison failures if the acronym ever contains chars that CGI.escape would encode. --- helpers/slices_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/slices_helper.rb b/helpers/slices_helper.rb index ebd21e824..94c989601 100644 --- a/helpers/slices_helper.rb +++ b/helpers/slices_helper.rb @@ -25,7 +25,7 @@ def ontology_in_slice?(acronym) slice = current_slice return true unless slice - ont_id = (LinkedData::Models::Ontology.id_prefix + acronym).to_s + ont_id = LinkedData::Models::Ontology.id_from_unique_attribute(:acronym, acronym).to_s slice.ontology_id_set.include?(ont_id) end From 46b23722f4c34cd3aacd5fed16e39da0c95e2d88 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 09:05:28 -0700 Subject: [PATCH 121/173] remove unnesesary platform constrains from Gemfile --- Gemfile.lock | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8e3488598..e6e15c152 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 043a43cc5b484a98c856c48a55cd1746c570a74d + revision: bbc91e4864630e46ab2e31451b71fbea4b879832 branch: master specs: ncbo_cron (0.0.1) @@ -51,7 +51,7 @@ GIT ncbo_annotator ontologies_linked_data redis - rufus-scheduler (~> 2.0.24) + rufus-scheduler (~> 3.9) GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git @@ -178,6 +178,8 @@ GEM base64 (~> 0.3) drb (2.2.3) ed25519 (1.4.0) + et-orbi (1.4.0) + tzinfo faraday (2.14.1) faraday-net_http (>= 2.0, < 3.5) json @@ -190,15 +192,12 @@ GEM faraday (~> 2.0) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) - ffi (1.17.4-aarch64-linux-musl) - ffi (1.17.4-arm-linux-gnu) - ffi (1.17.4-arm-linux-musl) ffi (1.17.4-arm64-darwin) - ffi (1.17.4-x86-linux-gnu) - ffi (1.17.4-x86-linux-musl) ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) - ffi (1.17.4-x86_64-linux-musl) + fugit (1.12.1) + et-orbi (~> 1.4) + raabro (~> 1.4) gapic-common (1.1.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) @@ -228,7 +227,6 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) - google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -254,9 +252,6 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) - grpc (1.70.1-x86-linux) - google-protobuf (>= 3.25, < 5.0) - googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -366,6 +361,7 @@ GEM method_source (~> 1.0) reline (>= 0.6.0) public_suffix (7.0.5) + raabro (1.4.0) racc (1.8.1) rack (3.2.6) rack-accept (0.4.5) @@ -449,8 +445,8 @@ GEM ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) rubyzip (3.2.2) - rufus-scheduler (2.0.24) - tzinfo (>= 0.3.22) + rufus-scheduler (3.9.2) + fugit (~> 1.1, >= 1.11.1) securerandom (0.4.1) signet (0.21.0) addressable (~> 2.8) @@ -513,20 +509,11 @@ GEM webrick (1.9.2) PLATFORMS - aarch64-linux aarch64-linux-gnu - aarch64-linux-musl - arm-linux-gnu - arm-linux-musl arm64-darwin ruby - x86-linux - x86-linux-gnu - x86-linux-musl x86_64-darwin - x86_64-linux x86_64-linux-gnu - x86_64-linux-musl DEPENDENCIES activesupport @@ -621,21 +608,17 @@ CHECKSUMS down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 + et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df - ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 - ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 - ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b - ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf - ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d - ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e + fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba goo (0.0.2) @@ -648,7 +631,6 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c - google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -657,7 +639,6 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 - grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -719,6 +700,7 @@ CHECKSUMS prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 + raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2 rack-accept (0.4.5) sha256=66247b5449db64ebb93ae2ec4af4764b87d1ae8a7463c7c68893ac13fa8d4da2 @@ -756,7 +738,7 @@ CHECKSUMS ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c - rufus-scheduler (2.0.24) sha256=cf1b6ebe4835368d48e5ec9fd275327ffb03fc566fd1609744b76749b32ad446 + rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 shotgun (0.9.2) signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b From 31bb035e273b47cf6ccf09d04ff79739f0d51586 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 10:48:00 -0700 Subject: [PATCH 122/173] re-enable newrelic --- Gemfile | 3 +++ Gemfile.lock | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 6b04d1a13..3c07bb4a2 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,9 @@ gem 'redis-rack-cache' gem 'redis' gem 'redis-store' +# Monitoring +gem 'newrelic_rpm' + # HTTP server gem 'unicorn' gem 'unicorn-worker-killer' diff --git a/Gemfile.lock b/Gemfile.lock index 25fed09c3..1275212d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: a4768dd3e85ab853765a6825760fc950f72b9ae4 + revision: e8952f8bc089609f7e38479d5c573d0e580ed556 branch: develop specs: ncbo_cron (0.0.1) @@ -350,6 +350,8 @@ GEM net-protocol net-ssh (7.3.2) netrc (0.11.0) + newrelic_rpm (10.4.0) + logger oj (3.17.0) bigdecimal (>= 3.0) ostruct (>= 0.2) @@ -561,6 +563,7 @@ DEPENDENCIES ncbo_cron! ncbo_ontology_recommender! net-ftp + newrelic_rpm oj ontologies_linked_data! ontoportal_testkit! @@ -713,6 +716,7 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.2) sha256=65029e213c380e20e5fd92ece663934ab0a0fe888e0cd7cc6a5b664074362dd4 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f + newrelic_rpm (10.4.0) sha256=36e3bc31adc89c3fe2056d1014a4d93b38bb63050050a1a442b35c4559531291 oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) From 5504f652b3bc929aaa081a684fea7aa608921ff7 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 11:16:57 -0700 Subject: [PATCH 123/173] re-enable newrelic --- app.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.rb b/app.rb index 08ed31a42..3f73742bd 100644 --- a/app.rb +++ b/app.rb @@ -172,6 +172,9 @@ require_relative 'config/unicorn_workerkiller' end +# Add New Relic last to allow Rack middleware instrumentation +require 'newrelic_rpm' + # Initialize the app require_relative 'init' From 58cc1f9a6aadd426b81ad589f30186fdcfc312b0 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 11:28:18 -0700 Subject: [PATCH 124/173] re-enable newrelic --- config/deploy.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/deploy.rb b/config/deploy.rb index a764cd9fb..9c0b599ce 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -108,6 +108,7 @@ after :updating, :get_config after :publishing, :restart + after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do From 6ec8414f5c3445e609cddfda14c8bbe118cbd909 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 11:29:41 -0700 Subject: [PATCH 125/173] re-enable newrelic --- Capfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Capfile b/Capfile index c01b1e450..6c6018e1b 100644 --- a/Capfile +++ b/Capfile @@ -22,5 +22,8 @@ require 'capistrano/bundler' # require 'capistrano/rails/assets' # require 'capistrano/rails/migrations' require 'capistrano/locally' + +# announce deployments in NewRelic +require 'new_relic/recipes' # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } From 2f1714432512b9c21fb3e34f1c10abdb53e7f536 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 11:40:54 -0700 Subject: [PATCH 126/173] re-enable newrelic integration (#211) re-enable newrelic --- Capfile | 3 +++ Gemfile | 3 +++ Gemfile.lock | 8 ++++++-- app.rb | 3 +++ config/deploy.rb | 1 + 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Capfile b/Capfile index c01b1e450..6c6018e1b 100644 --- a/Capfile +++ b/Capfile @@ -22,5 +22,8 @@ require 'capistrano/bundler' # require 'capistrano/rails/assets' # require 'capistrano/rails/migrations' require 'capistrano/locally' + +# announce deployments in NewRelic +require 'new_relic/recipes' # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } diff --git a/Gemfile b/Gemfile index 986deb641..1310694a9 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,9 @@ gem 'redis-rack-cache' gem 'redis' gem 'redis-store' +# Monitoring +gem 'newrelic_rpm' + # HTTP server gem 'unicorn' gem 'unicorn-worker-killer' diff --git a/Gemfile.lock b/Gemfile.lock index e6e15c152..3c9a18c89 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: bbc91e4864630e46ab2e31451b71fbea4b879832 - branch: master + revision: e8952f8bc089609f7e38479d5c573d0e580ed556 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -340,6 +340,8 @@ GEM net-protocol net-ssh (7.3.2) netrc (0.11.0) + newrelic_rpm (10.4.0) + logger oj (3.17.0) bigdecimal (>= 3.0) ostruct (>= 0.2) @@ -542,6 +544,7 @@ DEPENDENCIES ncbo_cron! ncbo_ontology_recommender! net-ftp + newrelic_rpm oj ontologies_linked_data! ontoportal_testkit! @@ -686,6 +689,7 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.2) sha256=65029e213c380e20e5fd92ece663934ab0a0fe888e0cd7cc6a5b664074362dd4 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f + newrelic_rpm (10.4.0) sha256=36e3bc31adc89c3fe2056d1014a4d93b38bb63050050a1a442b35c4559531291 oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) diff --git a/app.rb b/app.rb index 08ed31a42..3f73742bd 100644 --- a/app.rb +++ b/app.rb @@ -172,6 +172,9 @@ require_relative 'config/unicorn_workerkiller' end +# Add New Relic last to allow Rack middleware instrumentation +require 'newrelic_rpm' + # Initialize the app require_relative 'init' diff --git a/config/deploy.rb b/config/deploy.rb index a764cd9fb..9c0b599ce 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -108,6 +108,7 @@ after :updating, :get_config after :publishing, :restart + after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do From 29acae6d08d8beafff1421ea9cc1888fdcea09e1 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 11:44:32 -0700 Subject: [PATCH 127/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3c9a18c89..b17991bac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: e8952f8bc089609f7e38479d5c573d0e580ed556 - branch: develop + revision: bbc91e4864630e46ab2e31451b71fbea4b879832 + branch: master specs: ncbo_cron (0.0.1) dante From b7e10360fd2f50c6ea871cced2d067ead4fc08e9 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 12:03:57 -0700 Subject: [PATCH 128/173] remove agent based newrelic deployment recording --- Capfile | 2 -- Gemfile.lock | 4 ++-- config/deploy.rb | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Capfile b/Capfile index 6c6018e1b..720889327 100644 --- a/Capfile +++ b/Capfile @@ -23,7 +23,5 @@ require 'capistrano/bundler' # require 'capistrano/rails/migrations' require 'capistrano/locally' -# announce deployments in NewRelic -require 'new_relic/recipes' # Loads custom tasks from `lib/capistrano/tasks' if you have any defined. Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } diff --git a/Gemfile.lock b/Gemfile.lock index 3c9a18c89..b17991bac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: e8952f8bc089609f7e38479d5c573d0e580ed556 - branch: develop + revision: bbc91e4864630e46ab2e31451b71fbea4b879832 + branch: master specs: ncbo_cron (0.0.1) dante diff --git a/config/deploy.rb b/config/deploy.rb index 9c0b599ce..a764cd9fb 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -108,7 +108,6 @@ after :updating, :get_config after :publishing, :restart - after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do From b68115c122ea33c56992b8da27138d7506927528 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 12:09:43 -0700 Subject: [PATCH 129/173] remove agent based newrelic deployment recording --- config/deploy.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/deploy.rb b/config/deploy.rb index 9c0b599ce..a764cd9fb 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -108,7 +108,6 @@ after :updating, :get_config after :publishing, :restart - after :restart, "newrelic:notice_deployment" after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do From b85ee2bebb56cb7ca75b7915505ac95409df6ce8 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 14:47:20 -0700 Subject: [PATCH 130/173] fix /documentation NameError by extracting home helpers to HomeHelper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under sinatra-contrib 4.2.1 + mustermann 3.0, the before-filter that Sinatra::Namespace uses to mix its namespace module into each request instance (`before { extend(@namespace = namespace) }`) compiles for `namespace "/"` to a pattern that matches only `/` and not sub-paths like `/documentation` or `/metadata/:class`. Methods defined with bare `def` inside the namespace block were therefore unreachable from those routes, producing: NameError: undefined local variable or method `metadata_all' for # Move the home-controller helpers (metadata_all, metadata, resource_collection_link, sample_objects, hypermedia_links, routes_by_class, route_to_class_map, routes_list, parse_route, safe_type_uri, and CLASS_MAP) out of `namespace "/"` into a proper `Sinatra::Helpers::HomeHelper` module registered via the top-level `helpers` DSL — the same shape every other helper in this repo uses. Helpers now attach to Sinatra::Application at class-load time and no longer depend on the namespace before-filter firing. Add a regression test that exercises GET /documentation. Fixes ncbo/ontologies_api#212 --- controllers/home_controller.rb | 229 --------------------- helpers/home_helper.rb | 240 +++++++++++++++++++++++ test/controllers/test_home_controller.rb | 11 ++ 3 files changed, 251 insertions(+), 229 deletions(-) create mode 100644 helpers/home_helper.rb diff --git a/controllers/home_controller.rb b/controllers/home_controller.rb index 2d2490f53..58b4cad76 100644 --- a/controllers/home_controller.rb +++ b/controllers/home_controller.rb @@ -2,10 +2,6 @@ class HomeController < ApplicationController - CLASS_MAP = { - Property: "LinkedData::Models::ObjectProperty" - } - namespace "/" do get do @@ -36,230 +32,5 @@ class HomeController < ApplicationController haml "documentation/metadata".to_sym, :layout => "documentation/layout".to_sym end - def resource_collection_link(cls) - resource = @metadata[:cls].name.split("::").last - return "" if resource.nil? - - resource_path = "/" + resource.underscore.pluralize - - case - when resource == "Class" - "Example: "\ - ""\ - "/ontologies/SNOMEDCT/classes/http%3A%2F%2Fpurl.bioontology.org%2Fontology%2FSNOMEDCT%2F410607006" - when resource == "Instance" - "Example: "\ - ""\ - "/ontologies/CTX/classes/http%3A%2F%2Fwww.owl-ontologies.com%2FOntologyXCT.owl%23Eyelid/instances" - when resource == "Mapping" - "Example: "\ - ""\ - "/ontologies/SNOMEDCT/classes/http%3A%2F%2Fpurl.bioontology.org%2Fontology%2FSNOMEDCT%2F410607006/mappings" - when resource == "Note" - "Example: /ontologies/NCIT/notes" - when resource == "OntologySubmission" - "Example: "\ - ""\ - "/ontologies/NCIT/submissions?display=submissionId,version" - when (routes_list().include? resource_path) == false - "Example: coming soon" - else - "Resource collection: #{resource_path}" - end - end - - def metadata(cls) - unless cls.is_a?(Class) - cls = cls.singularize - cls = LinkedData::Models.const_get(cls) - end - metadata_all[cls] - end - - def sample_objects - ontology = LinkedData::Models::Ontology.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO", acronym: "BRO") - submission = LinkedData::Models::OntologySubmission.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO/submissions/1", ontology: ontology) - cls = LinkedData::Models::Class.read_only(id: "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Ontology_Development_and_Management", submission: submission) - return { - LinkedData::Models::Ontology.type_uri => ontology, - LinkedData::Models::Class.type_uri => cls - } - end - - def metadata_all - return @metadata_all_info if @metadata_all_info - ld_classes = ObjectSpace.each_object(Class).select { |klass| klass < LinkedData::Hypermedia::Resource } - info = {} - ld_classes.each do |cls| - next if routes_by_class[cls].nil? || routes_by_class[cls].empty? - if cls.respond_to?(:attributes) - attributes = (cls.attributes(:all) + cls.hypermedia_settings[:serialize_methods]).uniq - else - attributes = cls.instance_methods(false) - end - attributes_info = {} - attributes.each do |attribute| - next if cls.hypermedia_settings[:serialize_never].include?(attribute) - - if cls.ancestors.include?(LinkedData::Models::Base) - model_cls = cls.range(attribute) - if model_cls - type = model_cls.type_uri if model_cls.respond_to?("type_uri") - end - - shows_default = cls.hypermedia_settings[:serialize_default].empty? ? true : cls.hypermedia_settings[:serialize_default].include?(attribute) - - schema = cls.attribute_settings(attribute) rescue nil - schema ||= {} - attributes_info[attribute] = { - type: type || "", - shows_default: shows_default || " ", - unique: cls.unique?(attribute) || " ", - required: cls.required?(attribute) || " ", - list: cls.list?(attribute) || " ", - cardinality: cls.cardinality(attribute) || " " - } - else - attributes_info[attribute] = { - type: "", - shows_default: " ", - unique: " ", - required: " ", - list: " ", - cardinality: " " - } - end - end - - cls_info = { - attributes: attributes_info, - uri: safe_type_uri(cls), - cls: cls - } - - info[cls] = cls_info - end - - # Sort by 'shown by default' - info.each do |cls, cls_props| - shown = {} - not_shown = {} - cls_props[:attributes].each {|attr,values| values[:shows_default] ? shown[attr] = values : not_shown[attr] = values} - cls_props[:attributes] = shown.merge(not_shown) - end - - @metadata_all_info = info - info - end - - def hypermedia_links(cls) - cls.hypermedia_settings[:link_to] - end - - def routes_by_class - return @routes_by_class if @routes_by_class - all_routes = Sinatra::Application.routes - routes_by_file = {} - all_routes.each do |method, routes| - routes.each do |route| - route_info = parse_route(method, route) - next if route_info[:file].nil? - routes_by_file[route_info[:file]] ||= [] - routes_by_file[route_info[:file]] << route_info - end - end - routes_by_class = {} - routes_by_file.each do |file, routes| - cls_name = file.split("/").last.gsub(".rb", "").classify.gsub("Controller", "").singularize - cls = LinkedData::Models.const_get(cls_name) rescue nil - - # Check sub-modules for classes (IE LinkedData::Models::Notes for LinkedData::Models::Notes::Reply) - if cls.nil? - LinkedData::Models.constants.each do |const| - sub_cls = LinkedData::Models.const_get(const).const_get(cls_name) rescue nil - cls = sub_cls unless sub_cls.nil? - end - end - - # Check the map of NON-ONE-TO-ONE mappings - if cls.nil? - if CLASS_MAP.include?(cls_name.to_sym) - cls = CLASS_MAP[cls_name.to_sym].constantize - end - end - - next if cls.nil? - - routes.each do |route| - next if route[:verb] == "HEAD" - routes_by_class[cls] ||= [] - routes_by_class[cls] << [route[:verb], route[:path]] - end - end - @routes_by_class = routes_by_class - routes_by_class - end - - def route_to_class_map - return @route_to_class_map if @route_to_class_map - map = {} - routes_by_class.each do |cls, routes| - routes.each do |route| - map[route[1]] = cls - end - end - @route_to_class_map = map - map - end - - def routes_list - return @navigable_routes if @navigable_routes - all_routes = Sinatra::Application.routes - get_routes = all_routes["GET"] || all_routes[:GET] || [] - navigable_routes = get_routes.map { |route| parse_route("GET", route)[:path] }.uniq - @navigable_routes = navigable_routes - navigable_routes - end - - # Sinatra < 4 routes are route objects; Sinatra 4 routes are arrays. - # Normalize both to a common shape. - def parse_route(method, route) - if route.respond_to?(:path) && route.respond_to?(:file) - return { verb: route.verb.to_s, path: route.path.to_s.split("?").first, file: route.file } - end - - if route.is_a?(Array) - pattern = route[0] - wrapper_proc = route[-1] - original_block = nil - file = nil - - if wrapper_proc.respond_to?(:binding) - begin - route_binding = wrapper_proc.binding - if route_binding.local_variables.include?(:block) - original_block = route_binding.local_variable_get(:block) - end - rescue StandardError - # ignore and leave file nil - end - end - - if original_block.respond_to?(:source_location) - file = original_block.source_location&.first - end - return { verb: method.to_s, path: pattern.to_s.split("?").first, file: file } - end - - { verb: method.to_s, path: "", file: nil } - end - - def safe_type_uri(cls) - return nil if cls.nil? || !cls.respond_to?(:type_uri) - cls.type_uri - rescue NoMethodError - nil - end - end end diff --git a/helpers/home_helper.rb b/helpers/home_helper.rb new file mode 100644 index 000000000..01c1a2477 --- /dev/null +++ b/helpers/home_helper.rb @@ -0,0 +1,240 @@ +require 'sinatra/base' + +module Sinatra + module Helpers + module HomeHelper + + CLASS_MAP = { + Property: "LinkedData::Models::ObjectProperty" + } + + def resource_collection_link(cls) + resource = @metadata[:cls].name.split("::").last + return "" if resource.nil? + + resource_path = "/" + resource.underscore.pluralize + + case + when resource == "Class" + "Example: "\ + ""\ + "/ontologies/SNOMEDCT/classes/http%3A%2F%2Fpurl.bioontology.org%2Fontology%2FSNOMEDCT%2F410607006" + when resource == "Instance" + "Example: "\ + ""\ + "/ontologies/CTX/classes/http%3A%2F%2Fwww.owl-ontologies.com%2FOntologyXCT.owl%23Eyelid/instances" + when resource == "Mapping" + "Example: "\ + ""\ + "/ontologies/SNOMEDCT/classes/http%3A%2F%2Fpurl.bioontology.org%2Fontology%2FSNOMEDCT%2F410607006/mappings" + when resource == "Note" + "Example: /ontologies/NCIT/notes" + when resource == "OntologySubmission" + "Example: "\ + ""\ + "/ontologies/NCIT/submissions?display=submissionId,version" + when (routes_list().include? resource_path) == false + "Example: coming soon" + else + "Resource collection: #{resource_path}" + end + end + + def metadata(cls) + unless cls.is_a?(Class) + cls = cls.singularize + cls = LinkedData::Models.const_get(cls) + end + metadata_all[cls] + end + + def sample_objects + ontology = LinkedData::Models::Ontology.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO", acronym: "BRO") + submission = LinkedData::Models::OntologySubmission.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO/submissions/1", ontology: ontology) + cls = LinkedData::Models::Class.read_only(id: "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Ontology_Development_and_Management", submission: submission) + return { + LinkedData::Models::Ontology.type_uri => ontology, + LinkedData::Models::Class.type_uri => cls + } + end + + def metadata_all + return @metadata_all_info if @metadata_all_info + ld_classes = ObjectSpace.each_object(Class).select { |klass| klass < LinkedData::Hypermedia::Resource } + info = {} + ld_classes.each do |cls| + next if routes_by_class[cls].nil? || routes_by_class[cls].empty? + if cls.respond_to?(:attributes) + attributes = (cls.attributes(:all) + cls.hypermedia_settings[:serialize_methods]).uniq + else + attributes = cls.instance_methods(false) + end + attributes_info = {} + attributes.each do |attribute| + next if cls.hypermedia_settings[:serialize_never].include?(attribute) + + if cls.ancestors.include?(LinkedData::Models::Base) + model_cls = cls.range(attribute) + if model_cls + type = model_cls.type_uri if model_cls.respond_to?("type_uri") + end + + shows_default = cls.hypermedia_settings[:serialize_default].empty? ? true : cls.hypermedia_settings[:serialize_default].include?(attribute) + + schema = cls.attribute_settings(attribute) rescue nil + schema ||= {} + attributes_info[attribute] = { + type: type || "", + shows_default: shows_default || " ", + unique: cls.unique?(attribute) || " ", + required: cls.required?(attribute) || " ", + list: cls.list?(attribute) || " ", + cardinality: cls.cardinality(attribute) || " " + } + else + attributes_info[attribute] = { + type: "", + shows_default: " ", + unique: " ", + required: " ", + list: " ", + cardinality: " " + } + end + end + + cls_info = { + attributes: attributes_info, + uri: safe_type_uri(cls), + cls: cls + } + + info[cls] = cls_info + end + + # Sort by 'shown by default' + info.each do |cls, cls_props| + shown = {} + not_shown = {} + cls_props[:attributes].each {|attr,values| values[:shows_default] ? shown[attr] = values : not_shown[attr] = values} + cls_props[:attributes] = shown.merge(not_shown) + end + + @metadata_all_info = info + info + end + + def hypermedia_links(cls) + cls.hypermedia_settings[:link_to] + end + + def routes_by_class + return @routes_by_class if @routes_by_class + all_routes = Sinatra::Application.routes + routes_by_file = {} + all_routes.each do |method, routes| + routes.each do |route| + route_info = parse_route(method, route) + next if route_info[:file].nil? + routes_by_file[route_info[:file]] ||= [] + routes_by_file[route_info[:file]] << route_info + end + end + routes_by_class = {} + routes_by_file.each do |file, routes| + cls_name = file.split("/").last.gsub(".rb", "").classify.gsub("Controller", "").singularize + cls = LinkedData::Models.const_get(cls_name) rescue nil + + # Check sub-modules for classes (IE LinkedData::Models::Notes for LinkedData::Models::Notes::Reply) + if cls.nil? + LinkedData::Models.constants.each do |const| + sub_cls = LinkedData::Models.const_get(const).const_get(cls_name) rescue nil + cls = sub_cls unless sub_cls.nil? + end + end + + # Check the map of NON-ONE-TO-ONE mappings + if cls.nil? + if CLASS_MAP.include?(cls_name.to_sym) + cls = CLASS_MAP[cls_name.to_sym].constantize + end + end + + next if cls.nil? + + routes.each do |route| + next if route[:verb] == "HEAD" + routes_by_class[cls] ||= [] + routes_by_class[cls] << [route[:verb], route[:path]] + end + end + @routes_by_class = routes_by_class + routes_by_class + end + + def route_to_class_map + return @route_to_class_map if @route_to_class_map + map = {} + routes_by_class.each do |cls, routes| + routes.each do |route| + map[route[1]] = cls + end + end + @route_to_class_map = map + map + end + + def routes_list + return @navigable_routes if @navigable_routes + all_routes = Sinatra::Application.routes + get_routes = all_routes["GET"] || all_routes[:GET] || [] + navigable_routes = get_routes.map { |route| parse_route("GET", route)[:path] }.uniq + @navigable_routes = navigable_routes + navigable_routes + end + + # Sinatra < 4 routes are route objects; Sinatra 4 routes are arrays. + # Normalize both to a common shape. + def parse_route(method, route) + if route.respond_to?(:path) && route.respond_to?(:file) + return { verb: route.verb.to_s, path: route.path.to_s.split("?").first, file: route.file } + end + + if route.is_a?(Array) + pattern = route[0] + wrapper_proc = route[-1] + original_block = nil + file = nil + + if wrapper_proc.respond_to?(:binding) + begin + route_binding = wrapper_proc.binding + if route_binding.local_variables.include?(:block) + original_block = route_binding.local_variable_get(:block) + end + rescue StandardError + # ignore and leave file nil + end + end + + if original_block.respond_to?(:source_location) + file = original_block.source_location&.first + end + return { verb: method.to_s, path: pattern.to_s.split("?").first, file: file } + end + + { verb: method.to_s, path: "", file: nil } + end + + def safe_type_uri(cls) + return nil if cls.nil? || !cls.respond_to?(:type_uri) + cls.type_uri + rescue NoMethodError + nil + end + + end + end +end + +helpers Sinatra::Helpers::HomeHelper diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index bc4e64b9d..ac68a55a1 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -13,6 +13,17 @@ def test_home_index_returns_links_hash assert_operator body['links']['@context'].length, :>, 0 end + # Regression: ncbo/ontologies_api#212 + # Under sinatra-contrib 4.2.1, `namespace "/"`'s before-filter pattern + # does not match sub-paths, so helpers defined inside the namespace + # block are not mixed into the request instance and the route handler + # raises NameError: undefined local variable or method `metadata_all'. + def test_documentation_route_renders + get '/documentation' + assert last_response.ok?, get_errors(last_response) + assert_match(/ Date: Wed, 22 Apr 2026 15:14:51 -0700 Subject: [PATCH 131/173] drop dead `cardinality` column from HomeHelper#metadata_all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The producer (`cls.cardinality(attribute)`) was removed from goo in the AgroPortal fork in agroportal/goo#52 (commit 2206084, merged 2024-01-31) and subsequently synced into ncbo/goo via ncbo/goo#176 on 2024-04-03. The consumer — the `views/documentation/*.haml` tables — has no reference to `values[:cardinality]` either. The key in the attributes_info hash was being populated only to be thrown away. Delete the key from both branches of the conditional. No view change needed; the earlier `rescue nil` guard added in 1fe44f8 becomes unnecessary and is removed with it. --- helpers/home_helper.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/helpers/home_helper.rb b/helpers/home_helper.rb index 01c1a2477..5f56d04ea 100644 --- a/helpers/home_helper.rb +++ b/helpers/home_helper.rb @@ -88,8 +88,7 @@ def metadata_all shows_default: shows_default || " ", unique: cls.unique?(attribute) || " ", required: cls.required?(attribute) || " ", - list: cls.list?(attribute) || " ", - cardinality: cls.cardinality(attribute) || " " + list: cls.list?(attribute) || " " } else attributes_info[attribute] = { @@ -97,8 +96,7 @@ def metadata_all shows_default: " ", unique: " ", required: " ", - list: " ", - cardinality: " " + list: " " } end end From 99d0df108f82609fd8ebe99aa2becd70cd879de5 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 15:38:37 -0700 Subject: [PATCH 132/173] swap pandoc-ruby for kramdown to render :markdown in documentation view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `views/documentation/documentation.haml` contains four `:markdown` filter blocks that HAML delegates to Tilt. In the current bundle the only markdown-capable gem was `pandoc-ruby`, so Tilt selected its PandocTemplate, which shells out to an external `pandoc` binary. Our Docker image inherits from `ontoportal/testkit-base` and does not install that binary, so `/documentation` failed with `RuntimeError: sh: pandoc: command not found` in any environment without pandoc on the PATH. Replace `pandoc-ruby` with `kramdown`, a pure-Ruby renderer already known to Tilt (`tilt/kramdown.rb`). This removes the system-binary dependency entirely rather than matching agroportal's approach of installing pandoc in their Dockerfile. Performance is indistinguishable for four short blocks on a rarely-hit developer page; pure-Ruby avoids cross-architecture compile/install churn across containers. Verified post-install: `Tilt[:md] → Tilt::KramdownTemplate`. --- Gemfile | 2 +- Gemfile.lock | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 1310694a9..26f1d7452 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,7 @@ gem 'unicorn-worker-killer' # Templating gem 'haml', '~> 5.2.2' # pin see https://github.com/ncbo/ontologies_api/pull/107 gem 'rack-contrib' -gem 'pandoc-ruby' +gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) gem 'goo', github: 'ncbo/goo', branch: 'main' diff --git a/Gemfile.lock b/Gemfile.lock index b17991bac..6cd616969 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -284,6 +284,8 @@ GEM jwt (3.1.2) base64 kgio (2.11.4) + kramdown (2.5.2) + rexml (>= 3.4.4) language_server-protocol (3.17.0.5) libxml-ruby (6.0.0) link_header (0.0.8) @@ -349,7 +351,6 @@ GEM logger os (1.1.4) ostruct (0.6.3) - pandoc-ruby (2.1.10) parallel (1.28.0) parseconfig (1.1.2) parser (3.3.11.1) @@ -535,6 +536,7 @@ DEPENDENCIES haml (~> 5.2.2) json-ld (~> 3.2.0) json-schema + kramdown minitest minitest-hooks minitest-reporters @@ -548,7 +550,6 @@ DEPENDENCIES oj ontologies_linked_data! ontoportal_testkit! - pandoc-ruby parallel parseconfig rack @@ -657,6 +658,7 @@ CHECKSUMS json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 + kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc libxml-ruby (6.0.0) sha256=a9d9458d018dee591d0995fdc1110cd67ec32b7be67d36fdb9e0b01a4ca9dac4 link_header (0.0.8) sha256=15c65ce43b29f739b30d05e5f25c22c23797e89cf6f905dbb595fb4c70cb55f9 @@ -696,7 +698,6 @@ CHECKSUMS ontoportal_testkit (0.1.0) os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 - pandoc-ruby (2.1.10) sha256=37653d6b5e71657fb25b3cb230e6eebbfb8c925c7f1fcf69dfb6b929d12b74b2 parallel (1.28.0) sha256=33e6de1484baf2524792d178b0913fc8eb94c628d6cfe45599ad4458c638c970 parseconfig (1.1.2) sha256=e52247d15070fb47f9e58f44f7888d1e7f65775274cd60f9ab4b7acd7943b291 parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 From 5ca5f8d45837fba47db0b8e772de87beb9898c75 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 15:53:11 -0700 Subject: [PATCH 133/173] add regression tests for GET /metadata/:class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The home-helper extraction also restores `GET /metadata/:class`, which had been broken for years (ncbo/ontologies_api#37) and was broken again for a different reason under sinatra-contrib 4.2.1 (ncbo/ontologies_api#212). Lock the fix in with two tests: - /metadata/Metrics — exercises the common case (singularize + top-level LinkedData::Models::Metric lookup). - /metadata/Reply — exercises HomeHelper#routes_by_class's sub-module search branch (LinkedData::Models::Notes::Reply). --- test/controllers/test_home_controller.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index ac68a55a1..1c3e6a393 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -24,6 +24,24 @@ def test_documentation_route_renders assert_match(/ Date: Wed, 22 Apr 2026 17:20:30 -0700 Subject: [PATCH 134/173] resolve nested model classes in HomeHelper#metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `metadata(cls)` did a bare `LinkedData::Models.const_get(name)`, so requests like `GET /metadata/Reply` blew up with `NameError: uninitialized constant LinkedData::Models::Reply` — `Reply` lives under `LinkedData::Models::Notes`, not at the top level. `routes_by_class` already has sub-module search for the same reason; `metadata` was missing the mirror. Extract a small `resolve_model_class(name)` helper that tries the top-level lookup first and falls back to scanning `LinkedData::Models.constants` for the name, matching the behavior of `routes_by_class`. This restores `GET /metadata/Reply` and any other nested model class (e.g. `Users::Role`, `Users::NotificationType`). test_metadata_route_resolves_submodule_class now passes. --- helpers/home_helper.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/helpers/home_helper.rb b/helpers/home_helper.rb index 5f56d04ea..2b75b51ad 100644 --- a/helpers/home_helper.rb +++ b/helpers/home_helper.rb @@ -42,12 +42,24 @@ def resource_collection_link(cls) def metadata(cls) unless cls.is_a?(Class) - cls = cls.singularize - cls = LinkedData::Models.const_get(cls) + cls = resolve_model_class(cls.singularize) end metadata_all[cls] end + # Resolve a model class by bare name, checking LinkedData::Models first + # and falling back to sub-modules (e.g. LinkedData::Models::Notes::Reply + # for "Reply"). Mirrors the sub-module search in `routes_by_class`. + def resolve_model_class(name) + LinkedData::Models.const_get(name) + rescue NameError + LinkedData::Models.constants.each do |const| + sub_cls = LinkedData::Models.const_get(const).const_get(name) rescue nil + return sub_cls if sub_cls.is_a?(Class) + end + raise + end + def sample_objects ontology = LinkedData::Models::Ontology.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO", acronym: "BRO") submission = LinkedData::Models::OntologySubmission.read_only(id: LinkedData.settings.rest_url_prefix+"/ontologies/BRO/submissions/1", ontology: ontology) From d2e5b644b1a0c7e1d64d40bc0dccbef5ec09d983 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Wed, 22 Apr 2026 21:02:15 -0700 Subject: [PATCH 135/173] reword /metadata/:class 404 in user-facing vocabulary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous "No metadata for \`X\` — not a LinkedData model class" leaked the Ruby gem name and used "model class", terms API users don't encounter elsewhere. The BioPortal /documentation page uses "media type" for exactly these /metadata/:X URIs (they surface as JSON-LD @type / @context identifiers in responses, documented under "Media Types and Hypermedia Links"), so match that vocabulary and point the user at a concrete working example. Also route the response through the repo's `error` helper so the 404 comes back as the standard `{ errors: [...], status: 404 }` shape through LinkedData's content-negotiating serializer, matching every other error response in the codebase (no more one-off `halt 404, "string"`). Strengthen the regression test to assert the new phrasing appears in the body, not just the status code. --- controllers/home_controller.rb | 3 +++ helpers/home_helper.rb | 10 +++++++--- test/controllers/test_home_controller.rb | 13 +++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/controllers/home_controller.rb b/controllers/home_controller.rb index 58b4cad76..a80da920d 100644 --- a/controllers/home_controller.rb +++ b/controllers/home_controller.rb @@ -29,6 +29,9 @@ class HomeController < ApplicationController get "metadata/:class" do @metadata = metadata(params["class"]) + if @metadata.nil? + error 404, "'#{params["class"]}' is not a documented media type. See /documentation or try /metadata/Ontology." + end haml "documentation/metadata".to_sym, :layout => "documentation/layout".to_sym end diff --git a/helpers/home_helper.rb b/helpers/home_helper.rb index 2b75b51ad..48c7275c4 100644 --- a/helpers/home_helper.rb +++ b/helpers/home_helper.rb @@ -44,20 +44,24 @@ def metadata(cls) unless cls.is_a?(Class) cls = resolve_model_class(cls.singularize) end + return nil if cls.nil? metadata_all[cls] end # Resolve a model class by bare name, checking LinkedData::Models first # and falling back to sub-modules (e.g. LinkedData::Models::Notes::Reply # for "Reply"). Mirrors the sub-module search in `routes_by_class`. + # Returns nil when the name is not a valid constant or does not resolve + # to a class (e.g. attribute/property names like "created", "body"). def resolve_model_class(name) - LinkedData::Models.const_get(name) - rescue NameError + klass = LinkedData::Models.const_get(name) rescue nil + return klass if klass.is_a?(Class) + LinkedData::Models.constants.each do |const| sub_cls = LinkedData::Models.const_get(const).const_get(name) rescue nil return sub_cls if sub_cls.is_a?(Class) end - raise + nil end def sample_objects diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index 1c3e6a393..c4688e017 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -42,6 +42,19 @@ def test_metadata_route_resolves_submodule_class assert_match(/ Date: Wed, 22 Apr 2026 22:09:58 -0700 Subject: [PATCH 136/173] broaden /metadata/:class tests; narrow 404 test to bogus-only names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extend `test_metadata_route_renders_for_model_class` to loop over `Ontology`, `Metrics`, `Class` — covers plain top-level lookup (`Ontology`), singularization (`Metrics` → `Metric`), and a second plain case with a distinctive name (`Class`). All three hit the same `resolve_model_class` top-level branch, but `Ontology` was the one case we previously had no explicit coverage for. - Rename `test_metadata_route_returns_404_for_non_class_names` → `test_metadata_route_returns_404_for_bogus_names` and trim its list to `DefinitelyNotAModel`, `nonexistent_thing`, `xyzqux123` — guaranteed-nonexistent identifiers that will stay 404 regardless of future features. The previous list (`created`, `body`, `prefixIRI`, `name`, `omvacronym`) was misleading: those *are* attribute URIs the API emits in JSON-LD @context, currently 404'd as a stop-gap but tracked in ncbo/bioportal-project#388 for actual attribute-documentation rendering. Leaving them asserted as 404 would turn into a false regression signal when #388 lands. --- test/controllers/test_home_controller.rb | 27 +++++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index c4688e017..65a6c5eaf 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -29,9 +29,12 @@ def test_documentation_route_renders # for the same namespace-helper-resolution reason as /documentation, and # had been listed as broken in #37 since 2017. def test_metadata_route_renders_for_model_class - get '/metadata/Metrics' - assert last_response.ok?, get_errors(last_response) - assert_match(/ Date: Wed, 22 Apr 2026 23:47:19 -0700 Subject: [PATCH 137/173] reset branch specifier to develop --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 26f1d7452..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 6cd616969..3fdd5db08 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: fa850f46c94e09b6368ed47728b9cce05b7e9d54 - branch: main + revision: 90365864f67a9458011f16e1b9f44a73af0d3739 + branch: development specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: b216bdde2de471fc0f851556ffa2327333516e79 - branch: master + revision: 5243ea8db4302ca756c66bf50233e88606830326 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: bbc91e4864630e46ab2e31451b71fbea4b879832 - branch: master + revision: d92fd430629eb070ef5a2e01b4f613b3b1f05a5a + branch: develop specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: ddf6e3b207417e694727c2be3e0431687b1758d0 - branch: master + revision: fa30fe29838cc40377e05c663ca50ef260071e93 + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: fb7a292c7a97b9d19e359e20fe93c46131850d18 - branch: master + revision: 25b2776dfd71e3ca329ced716760cfaf8ef3bc9a + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: main + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From b96088751cf7aceb81338c8a5319685d52f93379 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Thu, 23 Apr 2026 00:17:33 -0700 Subject: [PATCH 138/173] reset branch specifier to master --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 9867a4b00..26f1d7452 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 3fdd5db08..8c4530e3e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 90365864f67a9458011f16e1b9f44a73af0d3739 - branch: development + revision: ee72f43daa37f02362da1b747f037c442cfbf112 + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 5243ea8db4302ca756c66bf50233e88606830326 - branch: develop + revision: b216bdde2de471fc0f851556ffa2327333516e79 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: d92fd430629eb070ef5a2e01b4f613b3b1f05a5a - branch: develop + revision: bbc91e4864630e46ab2e31451b71fbea4b879832 + branch: master specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: fa30fe29838cc40377e05c663ca50ef260071e93 - branch: develop + revision: ddf6e3b207417e694727c2be3e0431687b1758d0 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 25b2776dfd71e3ca329ced716760cfaf8ef3bc9a - branch: develop + revision: fb7a292c7a97b9d19e359e20fe93c46131850d18 + branch: master specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: development + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From 26f55082af4bb7f886fe5e1c99985d4e709b32f4 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 28 Apr 2026 01:34:48 -0700 Subject: [PATCH 139/173] use fix/users-endpoint-perf-with-security oLD --- Gemfile | 2 +- Gemfile.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 9867a4b00..c125a2585 100644 --- a/Gemfile +++ b/Gemfile @@ -55,7 +55,7 @@ gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'fix/users-endpoint-perf-with-security' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 3fdd5db08..4b402c1e7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 25b2776dfd71e3ca329ced716760cfaf8ef3bc9a - branch: develop + revision: d728fdc87974fb21d5aaad09e070f0b1fdf682d9 + branch: fix/users-endpoint-perf-with-security specs: ontologies_linked_data (0.0.1) activesupport @@ -173,7 +173,7 @@ GEM date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) - down (5.5.0) + down (5.6.0) addressable (~> 2.8) base64 (~> 0.3) drb (2.2.3) @@ -327,7 +327,7 @@ GEM uri (>= 0.11.1) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - net-imap (0.6.3) + net-imap (0.6.4) date net-protocol net-pop (0.1.2) @@ -609,7 +609,7 @@ CHECKSUMS date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 + down (5.6.0) sha256=48ec6ddb078cbf3b425d02596bb388303316f976143c6e94a7b3169d6712b593 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc @@ -683,7 +683,7 @@ CHECKSUMS net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 - net-imap (0.6.3) sha256=9bab75f876596d09ee7bf911a291da478e0cd6badc54dfb82874855ccc82f2ad + net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d From 5ab66a10ba13795311f2eed99c5c45e58c9f91f1 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 28 Apr 2026 10:10:01 -0700 Subject: [PATCH 140/173] Gemfile update --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index c125a2585..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -55,7 +55,7 @@ gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'fix/users-endpoint-perf-with-security' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 4b402c1e7..641c6b33d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: d728fdc87974fb21d5aaad09e070f0b1fdf682d9 - branch: fix/users-endpoint-perf-with-security + revision: 9c2cfd9f240a376382944cf3ccc5a7cda2ff57df + branch: develop specs: ontologies_linked_data (0.0.1) activesupport From 951b6c0a5f7ad0879bad68c1ce94f6d600e20a3f Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 28 Apr 2026 10:51:56 -0700 Subject: [PATCH 141/173] Gemfile update --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 641c6b33d..76b71771e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 9c2cfd9f240a376382944cf3ccc5a7cda2ff57df + revision: 24c5a6d0a9de0ec6510d2615cc2e98c93c370a4e branch: develop specs: ontologies_linked_data (0.0.1) From 14e5e23f1cf2b61e2c67c9f3426db8ce7ad344eb Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Tue, 28 Apr 2026 14:03:05 -0700 Subject: [PATCH 142/173] Gemfile update --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8c4530e3e..a15e693a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: bbc91e4864630e46ab2e31451b71fbea4b879832 + revision: 8e43d5c2a053accffe801ff523e14b29743a079a branch: master specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: fb7a292c7a97b9d19e359e20fe93c46131850d18 + revision: 32023829506089164a27da1e6aa05b901a019079 branch: master specs: ontologies_linked_data (0.0.1) @@ -173,7 +173,7 @@ GEM date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) - down (5.5.0) + down (5.6.0) addressable (~> 2.8) base64 (~> 0.3) drb (2.2.3) @@ -327,7 +327,7 @@ GEM uri (>= 0.11.1) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - net-imap (0.6.3) + net-imap (0.6.4) date net-protocol net-pop (0.1.2) @@ -609,7 +609,7 @@ CHECKSUMS date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 + down (5.6.0) sha256=48ec6ddb078cbf3b425d02596bb388303316f976143c6e94a7b3169d6712b593 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc @@ -683,7 +683,7 @@ CHECKSUMS net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 - net-imap (0.6.3) sha256=9bab75f876596d09ee7bf911a291da478e0cd6badc54dfb82874855ccc82f2ad + net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d From dc54aca21212caa6d226996984647ecd87d21246 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 28 Apr 2026 14:58:31 -0700 Subject: [PATCH 143/173] always paginate GET /users; default order_by username Drops the `if page?` guard so /users unconditionally returns a Page object. Adds a deterministic default sort (username asc) so paged responses are stable for clients walking nextPage links. Addresses production timeouts on /users?include=all. Pairs with ncbo/ontologies_linked_data#286 (idempotent User#admin?, drop inverse attrs from auth load) and the corresponding ontologies_api_ruby_client auto-paginate change. Tests updated for the paged response shape and cover ?pagesize and ?include=all combinations. --- controllers/users_controller.rb | 2 +- helpers/users_helper.rb | 5 +++-- test/controllers/test_users_controller.rb | 26 ++++++++++++++++++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/controllers/users_controller.rb b/controllers/users_controller.rb index 4e4f4db25..a35388c28 100644 --- a/controllers/users_controller.rb +++ b/controllers/users_controller.rb @@ -57,7 +57,7 @@ class UsersController < ApplicationController end end - # Display all users + # Display users get do check_last_modified_collection(User) reply get_users diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index 0669b8f87..cf99f6798 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -4,7 +4,7 @@ module Sinatra module Helpers module UsersHelper def get_users - attributes, page, size, _, _ = settings_params(LinkedData::Models::User) + attributes, page, size, order_by, _ = settings_params(LinkedData::Models::User) query = User.where.include(attributes) if params['search'] @@ -12,7 +12,8 @@ def get_users query = query.filter(filter) end - query = query.page(page, size) if page? + query = query.order_by(order_by || { username: :asc }) + query = query.page(page, size) query.all end diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb index 47c929c33..b7e05de0d 100644 --- a/test/controllers/test_users_controller.rb +++ b/test/controllers/test_users_controller.rb @@ -35,9 +35,29 @@ def test_admin_creation def test_all_users get '/users' assert last_response.ok? - users = MultiJson.load(last_response.body) + users_page = MultiJson.load(last_response.body) + users = users_page["collection"] + assert_equal 1, users_page["page"] assert users.any? {|u| u["username"].eql?("fred")} - assert users.length >= @@usernames.length + assert users_page["totalCount"] >= @@usernames.length + end + + def test_all_users_pagination + get '/users?pagesize=2' + assert last_response.ok? + users_page = MultiJson.load(last_response.body) + assert_equal 1, users_page["page"] + assert_equal 2, users_page["collection"].length + assert_equal 2, users_page["nextPage"] + end + + def test_all_users_include_all_is_paged + get '/users?include=all&pagesize=2' + assert last_response.ok? + users_page = MultiJson.load(last_response.body) + assert_equal 1, users_page["page"] + assert_equal 2, users_page["collection"].length + assert users_page["collection"].all? { |u| u.key?("created") } end def test_single_user @@ -249,4 +269,4 @@ def _create_admin_user(apikey: nil) true if user["role"].eql?(['ADMINISTRATOR']) end -end \ No newline at end of file +end From f05f568ecbd246dfa8306de7d0889b57952bcc42 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 28 Apr 2026 14:58:36 -0700 Subject: [PATCH 144/173] Gemfile.lock update --- Gemfile.lock | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 76b71771e..3a4e49faa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: d92fd430629eb070ef5a2e01b4f613b3b1f05a5a + revision: b0236e0f2ef9a2083a9c9a2c9df6da817d03aa84 branch: develop specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 24c5a6d0a9de0ec6510d2615cc2e98c93c370a4e + revision: cdbf8f6990f10181f3efa11afada051a8283978e branch: develop specs: ontologies_linked_data (0.0.1) @@ -173,7 +173,7 @@ GEM date (3.5.1) docile (1.4.1) domain_name (0.6.20240107) - down (5.6.0) + down (5.5.0) addressable (~> 2.8) base64 (~> 0.3) drb (2.2.3) @@ -192,9 +192,15 @@ GEM faraday (~> 2.0) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -227,6 +233,7 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -252,6 +259,9 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -327,7 +337,7 @@ GEM uri (>= 0.11.1) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - net-imap (0.6.4) + net-imap (0.6.3) date net-protocol net-pop (0.1.2) @@ -512,11 +522,20 @@ GEM webrick (1.9.2) PLATFORMS + aarch64-linux aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl arm64-darwin ruby + x86-linux + x86-linux-gnu + x86-linux-musl x86_64-darwin + x86_64-linux x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES activesupport @@ -609,7 +628,7 @@ CHECKSUMS date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - down (5.6.0) sha256=48ec6ddb078cbf3b425d02596bb388303316f976143c6e94a7b3169d6712b593 + down (5.5.0) sha256=787e14fcfe7824b8cac676c608359e4083b2e4d6e1d3b1745b79f27bcf931585 drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc @@ -619,9 +638,15 @@ CHECKSUMS faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 + ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 + ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf + ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d + ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -635,6 +660,7 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c + google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -643,6 +669,7 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 + grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -683,7 +710,7 @@ CHECKSUMS net-ftp (0.3.9) sha256=307817ccf7f428f79d083f7e36dbb46a9d1d375e0d23027824de1866f0b13b65 net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6 - net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b + net-imap (0.6.3) sha256=9bab75f876596d09ee7bf911a291da478e0cd6badc54dfb82874855ccc82f2ad net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 net-scp (4.1.0) sha256=a99b0b92a1e5d360b0de4ffbf2dc0c91531502d3d4f56c28b0139a7c093d1a5d From 08759174a180678bdd37985a038c9757ec8ce568 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 28 Apr 2026 16:33:16 -0700 Subject: [PATCH 145/173] fix /search and /property_search 400 when acronym filter is empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 388d1bd ("converted acronyms filter from Boolean to Term syntax") replaced get_quoted_field_query_param at the start of filter_query construction in BOTH search_helper.rb (line 160) and properties_search_helper.rb (line 48). The new term-syntax function correctly early-returns "" for an empty acronyms list (an empty terms-query would itself be malformed), but the rest of filter_query construction in both helpers implicitly relied on the prior function's vacuous `submissionAcronym:""` placeholder always producing a non-empty starting clause. When acronyms filtered to empty (e.g. ontology_types restriction matches nothing, or the requesting user has no access to any of the requested ontologies), filter_query was "" and the subsequent `<< " AND "` appends produced a stray-AND fq that Solr rejected with 400 (surfaced as 500 by the API), breaking both /search and /property_search for any call whose acronyms resolved empty. Fix: when filter_query is empty after the acronyms step, use Solr's match-all literal `*:*`. AND'ing further clauses onto `*:*` narrows correctly, producing well-formed queries semantically equivalent to the constraints that follow. Also more correct than the pre-388d1bd behavior, which always silently added `submissionAcronym:""` (matching zero docs) when acronyms was empty — search-without-acronyms now actually returns matches. The third in-tree call site (search_helper.rb:181 — valueset_root_ids) is unaffected: it's already guarded by `unless valueset_root_ids.empty?` on the line above, so the function input is guaranteed non-empty. Adds regression tests for both endpoints exercising the empty-acronyms path via ontology_types=NONEXISTENT. --- helpers/properties_search_helper.rb | 4 ++++ helpers/search_helper.rb | 4 ++++ .../controllers/test_properties_search_controller.rb | 10 ++++++++++ test/controllers/test_search_controller.rb | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/helpers/properties_search_helper.rb b/helpers/properties_search_helper.rb index b4597b0a9..948cc6ada 100644 --- a/helpers/properties_search_helper.rb +++ b/helpers/properties_search_helper.rb @@ -46,6 +46,10 @@ def get_properties_search_query(text, params) onts.select! { |o| ont_type = o.ontologyType.nil? ? "ONTOLOGY" : o.ontologyType.get_code_from_id; ontology_types.include?(ont_type) } unless ontology_types.empty? acronyms = restricted_ontologies_to_acronyms(params, onts) filter_query = get_terms_field_query_param(acronyms, "submissionAcronym") + # No acronym restriction: provide Solr's match-all literal so the + # subsequent `filter_query << " AND "` appends produce a + # well-formed `fq` instead of starting with a stray AND. + filter_query = "*:*" if filter_query.empty? ontology_types_clause = ontology_types.empty? ? "" : get_quoted_field_query_param(ontology_types, "OR", "ontologyType") filter_query = "#{filter_query} AND #{ontology_types_clause}" unless (ontology_types_clause.empty?) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index 87c1e723e..bc8489839 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -158,6 +158,10 @@ def get_term_search_query(text, params={}) onts.select! { |o| ont_type = o.ontologyType.nil? ? "ONTOLOGY" : o.ontologyType.get_code_from_id; ontology_types.include?(ont_type) } unless ontology_types.empty? acronyms = restricted_ontologies_to_acronyms(params, onts) filter_query = get_terms_field_query_param(acronyms, "submissionAcronym") + # No acronym restriction: provide Solr's match-all literal so the + # subsequent `filter_query << " AND "` appends produce a + # well-formed `fq` instead of starting with a stray AND. + filter_query = "*:*" if filter_query.empty? # add subtree filter query if not empty filter_query << subtree_filter_query diff --git a/test/controllers/test_properties_search_controller.rb b/test/controllers/test_properties_search_controller.rb index 7d2d961e5..54955efaf 100644 --- a/test/controllers/test_properties_search_controller.rb +++ b/test/controllers/test_properties_search_controller.rb @@ -76,4 +76,14 @@ def test_search_filters results = MultiJson.load(last_response.body) assert_equal 2, results["collection"].length end + + # Regression: same empty-acronym Solr fq bug as in /search — when + # ontology_types filters all candidates out, filter_query was "" and + # the subsequent " AND " appends produced a malformed fq. + def test_property_search_with_empty_acronym_filter_returns_ok + get '/property_search?q=anything&ontology_types=NONEXISTENT_TYPE' + assert last_response.ok?, "expected 200, got #{last_response.status}: #{last_response.body[0, 200]}" + results = MultiJson.load(last_response.body) + assert_equal 0, results["collection"].length + end end diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index 8ae369501..dfe75470c 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -101,6 +101,18 @@ def test_search_ontology_filter end end + # Regression: when the acronyms list filters down to empty (here via an + # ontology_types filter that matches no seeded ontology), the Solr fq used + # to start with " AND obsolete:false ..." — a malformed query rejected by + # Solr (400) and surfaced as 500 by the API. Fix substitutes Solr's + # match-all literal so the AND'd clauses concatenate cleanly. + def test_search_with_empty_acronym_filter_returns_ok + get "/search?q=anything&ontology_types=NONEXISTENT_TYPE" + assert last_response.ok?, "expected 200, got #{last_response.status}: #{last_response.body[0, 200]}" + results = MultiJson.load(last_response.body) + assert_equal 0, results["collection"].length + end + def test_search_other_filters acronym = "MCCLSEARCHTEST-0" get "/search?q=receptor%20antagonists&ontologies=#{acronym}&require_exact_match=true" From 4102a5b5d7f6fced835ffc231578ffa6d5f5ac8b Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Mon, 4 May 2026 15:17:34 -0700 Subject: [PATCH 146/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 76b71771e..6de3a864e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: d92fd430629eb070ef5a2e01b4f613b3b1f05a5a + revision: 0d1532220408006bd8e28f5017523db00abc87b0 branch: develop specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 24c5a6d0a9de0ec6510d2615cc2e98c93c370a4e + revision: cdbf8f6990f10181f3efa11afada051a8283978e branch: develop specs: ontologies_linked_data (0.0.1) From af9751b8cd0ec660db5dc0d5a35517bbf3866228 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Mon, 4 May 2026 15:40:08 -0700 Subject: [PATCH 147/173] fix trailing-slash 301 redirects downgrading https to http (issue #217) --- init.rb | 19 ++++++++- test/controllers/test_home_controller.rb | 53 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/init.rb b/init.rb index 0fd644a9c..0f11b3968 100644 --- a/init.rb +++ b/init.rb @@ -22,9 +22,26 @@ def self.registered(app) app.public_send(http_verb, "#{pattern}/") do pass unless request.path_info.end_with?('/') redirect_path = request.path_info.chomp('/') - redirect redirect_path, 301 + redirect canonical_redirect_url(redirect_path), 301 end end end end end + +helpers do + def canonical_redirect_url(path) + url = +"#{external_request_scheme}://#{request.host_with_port}#{path}" + url << "?#{request.query_string}" unless request.query_string.empty? + url + end + + # Rack 3 no longer trusts X-Forwarded-Proto on `request.scheme`, so a + # TLS-terminating proxy that forwards to the app over HTTP would otherwise + # cause us to emit `Location: http://...` for an https:// request. + def external_request_scheme + forwarded = request.get_header('HTTP_X_FORWARDED_PROTO').to_s + .split(',').first.to_s.strip.downcase + %w[http https].include?(forwarded) ? forwarded : request.scheme + end +end diff --git a/test/controllers/test_home_controller.rb b/test/controllers/test_home_controller.rb index 65a6c5eaf..cf2f8b04c 100644 --- a/test/controllers/test_home_controller.rb +++ b/test/controllers/test_home_controller.rb @@ -24,6 +24,59 @@ def test_documentation_route_renders assert_match(/ 'https' } + + assert_equal 301, last_response.status + assert_equal "https://#{last_request.host_with_port}/documentation?apikey=test-key", + last_response.headers['Location'] + end + + def test_trailing_slash_redirect_falls_back_to_request_scheme_without_forwarded_header + get '/documentation/' + + assert_equal 301, last_response.status + assert_equal "http://#{last_request.host_with_port}/documentation", + last_response.headers['Location'] + end + + def test_trailing_slash_redirect_ignores_invalid_forwarded_proto + get '/documentation/', {}, { 'HTTP_X_FORWARDED_PROTO' => 'javascript' } + + assert_equal 301, last_response.status + assert_equal "http://#{last_request.host_with_port}/documentation", + last_response.headers['Location'] + end + + # Per RFC 7239, a request that traversed multiple proxies appends to + # X-Forwarded-Proto as a comma-separated list (`https, http`); the leftmost + # value is the original client-facing scheme. + def test_trailing_slash_redirect_uses_first_value_in_chained_forwarded_proto + get '/documentation/', {}, { 'HTTP_X_FORWARDED_PROTO' => 'https, http' } + + assert_equal 301, last_response.status + assert_equal "https://#{last_request.host_with_port}/documentation", + last_response.headers['Location'] + end + + # Regression: ncbo/ontologies_api#217 reproduction case. The bug was first + # observed against `/ontologies/:ont/classes//paths_to_root/`, + # so the encoded `%2F`s in the class IRI must round-trip through the redirect + # unchanged. + def test_trailing_slash_redirect_preserves_url_encoded_path_segments + encoded_cls = 'http%3A%2F%2Fpurl.bioontology.org%2Fontology%2FSTY%2FT071' + get "/ontologies/STY/classes/#{encoded_cls}/paths_to_root/?apikey=test-key", + {}, { 'HTTP_X_FORWARDED_PROTO' => 'https' } + + assert_equal 301, last_response.status + assert_equal "https://#{last_request.host_with_port}/ontologies/STY/classes/#{encoded_cls}/paths_to_root?apikey=test-key", + last_response.headers['Location'] + end + # Regression: ncbo/ontologies_api#212 / #37 # Valid `/metadata/:class` paths were 500-ing under sinatra-contrib 4.2.1 # for the same namespace-helper-resolution reason as /documentation, and From c2590ada364ca0b27edc2def3163d8e8a12226df Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 4 May 2026 17:31:33 -0700 Subject: [PATCH 148/173] Gemfile.lock update --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d5e6382c7..ec272f040 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 0d1532220408006bd8e28f5017523db00abc87b0 - branch: develop + revision: 8e43d5c2a053accffe801ff523e14b29743a079a + branch: master specs: ncbo_cron (0.0.1) dante @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: cdbf8f6990f10181f3efa11afada051a8283978e - branch: develop + revision: 32023829506089164a27da1e6aa05b901a019079 + branch: master specs: ontologies_linked_data (0.0.1) activesupport From d6209db42af56de0228d69c9b87b912d5d15c100 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Fri, 8 May 2026 16:56:30 -0700 Subject: [PATCH 149/173] Gemfile & Gemfile.lock update --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 26f1d7452..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index ec272f040..63d91975c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: ee72f43daa37f02362da1b747f037c442cfbf112 - branch: main + revision: c3eaf856b25dc6ba5b9a7ca40bcfe340a42c543c + branch: development specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: b216bdde2de471fc0f851556ffa2327333516e79 - branch: master + revision: 5243ea8db4302ca756c66bf50233e88606830326 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 8e43d5c2a053accffe801ff523e14b29743a079a - branch: master + revision: 0d1532220408006bd8e28f5017523db00abc87b0 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: ddf6e3b207417e694727c2be3e0431687b1758d0 - branch: master + revision: fa30fe29838cc40377e05c663ca50ef260071e93 + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 32023829506089164a27da1e6aa05b901a019079 - branch: master + revision: cdbf8f6990f10181f3efa11afada051a8283978e + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: main + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From 02ee539767ec1f7bb87a92920752ed4ef9c1f4ca Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Fri, 8 May 2026 18:44:12 -0700 Subject: [PATCH 150/173] resolved #221 - Too many boolean clauses search exception is thrown when using Annotator --- controllers/search_controller.rb | 2 +- helpers/search_helper.rb | 2 +- test/controllers/test_search_controller.rb | 36 +++++++++++ test/helpers/test_search_helper.rb | 71 ++++++++++++++++++++++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 test/helpers/test_search_helper.rb diff --git a/controllers/search_controller.rb b/controllers/search_controller.rb index 88e18c3a3..317207350 100644 --- a/controllers/search_controller.rb +++ b/controllers/search_controller.rb @@ -85,7 +85,7 @@ class SearchController < ApplicationController fq = [] - fq << ontologies.map { |x| "ontology_t:\"#{x}\"" }.join(' OR ') unless ontologies.blank? + fq << get_terms_field_query_param(ontologies, "ontology_t") unless ontologies.blank? fq << types.map { |x| "type_t:\"#{x}\" OR type_txt:\"#{x}\"" }.join(' OR ') unless types.blank? diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index bc8489839..47ca20146 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -433,7 +433,7 @@ def populate_classes_from_search(classes, ontology_acronyms=nil) params.delete("ontology_acronyms") params.delete("q") params["qf"] = "resource_id" - params["fq"] << " AND #{get_quoted_field_query_param(class_ids, "OR", "resource_id")}" + params["fq"] << " AND #{get_terms_field_query_param(class_ids, "resource_id")}" params["rows"] = 99999 # Replace fake query with wildcard resp = LinkedData::Models::Class.submit_search_query("*:*", params) diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index dfe75470c..9b36f714f 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -68,6 +68,42 @@ def after_suite LinkedData::Models::Ontology.indexCommit end + # Follow-up regression for issue #221. The /search/ontologies/content endpoint + # auto-populates `ontologies` with all accessible acronyms when none is supplied + # by a non-admin caller. With BioPortal-scale data that list can exceed Solr's + # default `maxBooleanClauses` (1024), so the fq must route through the Solr + # `terms` parser, not a boolean OR expansion. + def test_content_search_uses_terms_parser_for_ontologies_fq + captured = nil + fake_connector = Object.new + fake_connector.define_singleton_method(:search) do |_query, params = {}| + captured = params.dup + { "response" => { "numFound" => 0, "docs" => [] } } + end + + original_new = SOLR::SolrConnector.method(:new) + SOLR::SolrConnector.define_singleton_method(:new) { |*_args, **_kw| fake_connector } + + acronyms = @@ontologies.map { |o| o.bring(:acronym).acronym }.join(",") + + begin + get "/search/ontologies/content?q=test&ontologies=#{acronyms}" + assert last_response.ok?, + "expected /content to succeed (got #{last_response.status}: #{last_response.body[0..200]})" + ensure + SOLR::SolrConnector.define_singleton_method(:new, original_new) + end + + refute_nil captured, "expected SolrConnector#search to be invoked" + fq_array = Array(captured[:fq]) + ontology_clause = fq_array.find { |f| f.to_s.include?("ontology_t") } + refute_nil ontology_clause, "expected an ontology_t filter in fq" + assert_match(/\{!terms f=ontology_t\}/, ontology_clause, + "fq must use the Solr terms parser to avoid 'too many boolean clauses' (issue #221 follow-up)") + refute ontology_clause.include?(" OR "), + "fq must not contain boolean OR-clauses for ontology acronyms (issue #221 follow-up)" + end + def test_search get '/search?q=ontology' assert last_response.ok? diff --git a/test/helpers/test_search_helper.rb b/test/helpers/test_search_helper.rb new file mode 100644 index 000000000..5a9464699 --- /dev/null +++ b/test/helpers/test_search_helper.rb @@ -0,0 +1,71 @@ +require_relative '../test_case_helpers' + +class TestSearchHelper < TestCaseHelpers + + # Regression coverage for issue #221: an annotator request with many class + # hits produced an `fq` with one Solr boolean clause per class id, exceeding + # Solr's default `maxBooleanClauses` (1024) and returning a 400 + # "too many boolean clauses". The fix routes class_id filters through the + # Solr `terms` query parser, which collapses to a single non-boolean clause. + + def test_get_terms_field_query_param_uses_solr_terms_parser + ids = ["http://x.org/A", "http://x.org/B", "http://x.org/C"] + query = helper.get_terms_field_query_param(ids, "resource_id") + + assert_match(/\A_query_:"\{!terms f=resource_id\}/, query, + "expected Solr terms-parser syntax") + assert_includes query, ids.join(","), + "expected ids to be comma-joined as terms-parser values" + refute_match(/\bOR\b/, query, + "must not emit boolean OR-clauses (issue #221)") + end + + def test_get_terms_field_query_param_returns_empty_for_empty_or_nil_input + assert_equal "", helper.get_terms_field_query_param([], "resource_id") + assert_equal "", helper.get_terms_field_query_param(nil, "resource_id") + end + + def test_populate_classes_from_search_uses_terms_parser_for_class_id_fq + fake_ont = Struct.new(:id).new("http://example.org/onto/TEST") + fake_sub = Struct.new(:ontology).new(fake_ont) + fake_cls = Struct.new(:id, :submission) + classes = (1..3).map { |i| fake_cls.new("http://example.org/class_#{i}", fake_sub) } + + h = helper + captured = nil + + # Bypass `get_term_search_query` (would otherwise hit the triplestore via + # `restricted_ontologies`). Seed `fq` with the Solr match-all literal -- + # `populate_classes_from_search` then appends ` AND ` to it. + h.define_singleton_method(:get_term_search_query) do |_text, params| + params["fq"] = "*:*" + "" + end + + # Capture the params built by `populate_classes_from_search` instead of + # actually hitting Solr. + klass = LinkedData::Models::Class + original_search = klass.method(:submit_search_query) + klass.define_singleton_method(:submit_search_query) do |_query, params| + captured = params.dup + { "response" => { "docs" => [] } } + end + + begin + h.populate_classes_from_search(classes, ["TEST"]) + ensure + klass.define_singleton_method(:submit_search_query, original_search) + h.singleton_class.send(:remove_method, :get_term_search_query) + end + + refute_nil captured, "expected submit_search_query to be invoked" + assert_match(/\{!terms f=resource_id\}/, captured["fq"], + "fq must use the Solr terms parser to avoid 'too many boolean clauses' (issue #221)") + refute captured["fq"].include?(" OR "), + "fq must not contain boolean OR-clauses for class_ids (issue #221)" + classes.each do |c| + assert_includes captured["fq"], c.id, + "fq must include each class id in the terms-parser values" + end + end +end From a70ddbee8437ed72a1b69421769eee03c893c5c1 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Fri, 8 May 2026 19:04:33 -0700 Subject: [PATCH 151/173] fixed #222 - NoMethodError at /annotator is thrown for certain Annotator calls --- helpers/search_helper.rb | 5 ++- test/helpers/test_search_helper.rb | 58 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb index 47ca20146..d2192897d 100644 --- a/helpers/search_helper.rb +++ b/helpers/search_helper.rb @@ -450,8 +450,11 @@ def populate_classes_from_search(classes, ontology_acronyms=nil) next unless old_class doc[:submission] = old_class.submission doc[:properties] = MultiJson.load(doc.delete(:propertyRaw)) if include_param_contains?(:properties) + # `read_only` derives Struct fields from `doc.keys`, so `prefLabel` + # must be seeded as a hash key — assigning it post-construction + # raises NoMethodError for docs whose Solr index lacks `prefLabel*`. + doc[:prefLabel] = pref_label_by_language(doc) instance = LinkedData::Models::Class.read_only(doc) - instance.prefLabel = pref_label_by_language(doc) classes_hash[ont_uri_class_uri] = instance end diff --git a/test/helpers/test_search_helper.rb b/test/helpers/test_search_helper.rb index 5a9464699..d74ad89de 100644 --- a/test/helpers/test_search_helper.rb +++ b/test/helpers/test_search_helper.rb @@ -25,6 +25,64 @@ def test_get_terms_field_query_param_returns_empty_for_empty_or_nil_input assert_equal "", helper.get_terms_field_query_param(nil, "resource_id") end + # Regression for issue #222. `LinkedData::Models::Class.read_only(doc)` returns + # a Struct whose fields are exactly `doc.keys`, so a Solr doc with no + # `prefLabel*` field produced a Struct that did not respond to `prefLabel=`, + # and `populate_classes_from_search` raised NoMethodError trying to assign + # `instance.prefLabel = ...`. The fix seeds `doc[:prefLabel]` before + # `read_only`, guaranteeing the Struct exposes a `prefLabel` accessor. + def test_populate_classes_from_search_handles_doc_without_preflabel + fake_ont = Struct.new(:id).new("http://example.org/onto/TEST") + fake_sub = Struct.new(:ontology).new(fake_ont) + fake_cls = Struct.new(:id, :submission) + cls = fake_cls.new("http://example.org/class_1", fake_sub) + + # Solr doc with no prefLabel-bearing field of any kind. + doc = { + "resource_id" => "http://example.org/class_1", + "ontologyId" => "http://example.org/onto/TEST/submissions/1", + "submissionAcronym" => "TEST", + "notation" => "test:Class1", + "obsolete" => false + } + + h = helper + + h.define_singleton_method(:get_term_search_query) do |_text, params| + params["fq"] = "*:*" + "" + end + # Sidestep the Sinatra request plumbing that downstream helpers depend on + # (`params`, `include_param_contains?`, `pref_label_by_language`) -- none + # of those are what's under test here. + h.define_singleton_method(:params) { {} } + h.define_singleton_method(:pref_label_by_language) { |_d| nil } + + klass = LinkedData::Models::Class + original_search = klass.method(:submit_search_query) + klass.define_singleton_method(:submit_search_query) do |_query, _params| + { "response" => { "docs" => [doc] } } + end + + result = nil + begin + result = h.populate_classes_from_search([cls], ["TEST"]) + ensure + klass.define_singleton_method(:submit_search_query, original_search) + h.singleton_class.send(:remove_method, :get_term_search_query) + h.singleton_class.send(:remove_method, :params) + h.singleton_class.send(:remove_method, :pref_label_by_language) + end + + refute_nil result, "expected populate_classes_from_search to return a hash" + assert_equal 1, result.size, "expected exactly one populated class" + instance = result.values.first + assert_respond_to instance, :prefLabel, + "the read_only Struct must expose a prefLabel accessor (issue #222)" + assert_nil instance.prefLabel, + "prefLabel should be nil when the Solr doc has no prefLabel field" + end + def test_populate_classes_from_search_uses_terms_parser_for_class_id_fq fake_ont = Struct.new(:id).new("http://example.org/onto/TEST") fake_sub = Struct.new(:ontology).new(fake_ont) From e828ac6d7f6e2715789751142ce7cdcfa4e13a06 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Sat, 9 May 2026 15:05:56 -0700 Subject: [PATCH 152/173] reverted changes to the /content endpoint --- controllers/search_controller.rb | 2 +- test/controllers/test_search_controller.rb | 36 ---------------------- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/controllers/search_controller.rb b/controllers/search_controller.rb index 317207350..88e18c3a3 100644 --- a/controllers/search_controller.rb +++ b/controllers/search_controller.rb @@ -85,7 +85,7 @@ class SearchController < ApplicationController fq = [] - fq << get_terms_field_query_param(ontologies, "ontology_t") unless ontologies.blank? + fq << ontologies.map { |x| "ontology_t:\"#{x}\"" }.join(' OR ') unless ontologies.blank? fq << types.map { |x| "type_t:\"#{x}\" OR type_txt:\"#{x}\"" }.join(' OR ') unless types.blank? diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb index 9b36f714f..dfe75470c 100644 --- a/test/controllers/test_search_controller.rb +++ b/test/controllers/test_search_controller.rb @@ -68,42 +68,6 @@ def after_suite LinkedData::Models::Ontology.indexCommit end - # Follow-up regression for issue #221. The /search/ontologies/content endpoint - # auto-populates `ontologies` with all accessible acronyms when none is supplied - # by a non-admin caller. With BioPortal-scale data that list can exceed Solr's - # default `maxBooleanClauses` (1024), so the fq must route through the Solr - # `terms` parser, not a boolean OR expansion. - def test_content_search_uses_terms_parser_for_ontologies_fq - captured = nil - fake_connector = Object.new - fake_connector.define_singleton_method(:search) do |_query, params = {}| - captured = params.dup - { "response" => { "numFound" => 0, "docs" => [] } } - end - - original_new = SOLR::SolrConnector.method(:new) - SOLR::SolrConnector.define_singleton_method(:new) { |*_args, **_kw| fake_connector } - - acronyms = @@ontologies.map { |o| o.bring(:acronym).acronym }.join(",") - - begin - get "/search/ontologies/content?q=test&ontologies=#{acronyms}" - assert last_response.ok?, - "expected /content to succeed (got #{last_response.status}: #{last_response.body[0..200]})" - ensure - SOLR::SolrConnector.define_singleton_method(:new, original_new) - end - - refute_nil captured, "expected SolrConnector#search to be invoked" - fq_array = Array(captured[:fq]) - ontology_clause = fq_array.find { |f| f.to_s.include?("ontology_t") } - refute_nil ontology_clause, "expected an ontology_t filter in fq" - assert_match(/\{!terms f=ontology_t\}/, ontology_clause, - "fq must use the Solr terms parser to avoid 'too many boolean clauses' (issue #221 follow-up)") - refute ontology_clause.include?(" OR "), - "fq must not contain boolean OR-clauses for ontology acronyms (issue #221 follow-up)" - end - def test_search get '/search?q=ontology' assert last_response.ok? From 1aa085111af028f68bad539e647e02a971c92bd7 Mon Sep 17 00:00:00 2001 From: Alex Skrenchuk Date: Mon, 11 May 2026 16:31:32 -0700 Subject: [PATCH 153/173] reset branch specifier to master --- Gemfile | 12 ++++++------ Gemfile.lock | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Gemfile b/Gemfile index 9867a4b00..26f1d7452 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 63d91975c..2ff3d2cbd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/alexskr/ontoportal_testkit.git - revision: 33f52810bdb576c25922fb739dea49507cf362a6 + revision: 9ab7d115e82bfb4c1e339ea9132aa31e5b07726e branch: main specs: ontoportal_testkit (0.1.0) @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: c3eaf856b25dc6ba5b9a7ca40bcfe340a42c543c - branch: development + revision: ee72f43daa37f02362da1b747f037c442cfbf112 + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 5243ea8db4302ca756c66bf50233e88606830326 - branch: develop + revision: b216bdde2de471fc0f851556ffa2327333516e79 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 0d1532220408006bd8e28f5017523db00abc87b0 - branch: develop + revision: 8e43d5c2a053accffe801ff523e14b29743a079a + branch: master specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: fa30fe29838cc40377e05c663ca50ef260071e93 - branch: develop + revision: e63da099a5d69cf08d2c1c0d58b2f80bd5d41bb0 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: cdbf8f6990f10181f3efa11afada051a8283978e - branch: develop + revision: 32023829506089164a27da1e6aa05b901a019079 + branch: master specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: development + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) @@ -269,7 +269,7 @@ GEM i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.2) - json (2.19.4) + json (2.19.5) json-canonicalization (0.4.0) json-ld (3.2.5) htmlentities (~> 4.3) @@ -305,10 +305,10 @@ GEM mime-types-data (~> 3.2025, >= 3.2025.0507) mime-types-data (3.2026.0414) mini_mime (1.1.5) - minitest (6.0.5) + minitest (6.0.6) drb (~> 2.0) prism (~> 1.5) - minitest-hooks (1.5.3) + minitest-hooks (1.5.4) minitest (> 5.3) minitest-reporters (1.8.0) ansi @@ -318,7 +318,7 @@ GEM minitest-stub_any_instance (1.0.3) mlanett-redis-lock (0.2.7) redis - multi_json (1.20.1) + multi_json (1.21.1) mustermann (3.1.1) net-ftp (0.3.9) net-protocol @@ -410,7 +410,7 @@ GEM rexml (~> 3.2) redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.28.0) + redis-client (0.29.0) connection_pool redis-rack-cache (2.2.1) rack-cache (>= 1.10, < 2) @@ -447,7 +447,7 @@ GEM prism (~> 1.7) ruby-progressbar (1.13.0) ruby-xxHash (0.4.0.2) - rubyzip (3.2.2) + rubyzip (3.3.0) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) securerandom (0.4.1) @@ -653,7 +653,7 @@ CHECKSUMS http-cookie (1.1.6) sha256=ba4b82be64de61dc281243dac70e3c382c45142f20268ed9276a3670c93feaa9 i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc - json (2.19.4) sha256=670a7d333fb3b18ca5b29cb255eb7bef099e40d88c02c80bd42a3f30fe5239ac + json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59 json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 @@ -671,12 +671,12 @@ CHECKSUMS mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 mime-types-data (3.2026.0414) sha256=461c4c655373a44bd6c5fe54bcf5b7776026ea96e808144b1ec465c4b99148cc mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef - minitest (6.0.5) sha256=f007d7246bf4feea549502842cd7c6aba8851cdc9c90ba06de9c476c0d01155c - minitest-hooks (1.5.3) sha256=ef50dd3bf47e6d1646befc358c640c71ca41f5650f0036b4c69929a44d6f32c4 + minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1 + minitest-hooks (1.5.4) sha256=1254069f3da51fea234dc4ff974108d03d19260ad5c4b78eed9695726a5069b8 minitest-reporters (1.8.0) sha256=8ce5280fb73ad3178ae525454df169b6f28c1b38b1d088ea91815d3a370ba384 minitest-stub_any_instance (1.0.3) sha256=d53ca295d173817f828789ac44ad3c2a4a0752166eea7a63c9ae026d9e7660e8 mlanett-redis-lock (0.2.7) sha256=55fea6e6fb9d9241d921187dd93f0d4ccc116138f873e5d5ee729f4c5aa9aad3 - multi_json (1.20.1) sha256=2f3934e805cc45ef91b551a1f89d0e9191abd06a5e04a2ef09a6a036c452ca6d + multi_json (1.21.1) sha256=e6126a31808e3b4d19f483c775ceac34df190dffa62adfb63a165ee14ba68080 mustermann (3.1.1) sha256=4c6170c7234d5499c345562ba7c7dfe73e1754286dcc1abb053064d66a127198 ncbo_annotator (0.0.1) ncbo_cron (0.0.1) @@ -730,7 +730,7 @@ CHECKSUMS rdf-vocab (3.3.3) sha256=d3b642edb37be7b37b73cafa9e01d55762f99292838e7b0868a3575bd297bf8b rdf-xsd (3.3.0) sha256=fab51d27b20344237d9b622ef32e83e4c44940840bfc76a245ce6b6abba44772 redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae - redis-client (0.28.0) sha256=888892f9cd8787a41c0ece00bdf5f556dfff7770326ce40bb2bc11f1bfec824b + redis-client (0.29.0) sha256=0c65bf1f8f6dca22063ddb085c0bb2054feef6f03a84869f4161b18a9a15bea3 redis-rack-cache (2.2.1) sha256=9c72978a6354e02efeb2f933dd32c94a4a13f1137dac492442126bf25cc19970 redis-store (1.11.0) sha256=edc4f3e239dcd1fdd9905584e6b1e623a84618e14436e6e8a07c70891008eda4 regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb @@ -743,7 +743,7 @@ CHECKSUMS rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 - rubyzip (3.2.2) sha256=c0ed99385f0625415c8f05bcae33fe649ed2952894a95ff8b08f26ca57ea5b3c + rubyzip (3.3.0) sha256=a372fc67892a4f8c0bc8ec906b720353d8e48807a64b2e63adf99b1e3583a034 rufus-scheduler (3.9.2) sha256=55fa9e4db0ff69d7f38c804f17baba0c9bce5cba39984ae3c5cf6c039d1323b9 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 shotgun (0.9.2) From 7df8a66e17356d1a016dfda2777d0a1d13e4bf64 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Mon, 11 May 2026 16:44:36 -0700 Subject: [PATCH 154/173] Gemfile.lock update --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2ff3d2cbd..497b232c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 8e43d5c2a053accffe801ff523e14b29743a079a + revision: 18a6c183d5dd59b3adda58af90bab334fb911537 branch: master specs: ncbo_cron (0.0.1) From 93635a31f0ea29077f4fa6f59b085e2e6dfe45e9 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Wed, 13 May 2026 11:16:27 -0700 Subject: [PATCH 155/173] Expand user search fields --- helpers/users_helper.rb | 14 +++++- test/controllers/test_users_controller.rb | 61 +++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index cf99f6798..544d093af 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -3,13 +3,14 @@ module Sinatra module Helpers module UsersHelper + USER_SEARCH_FIELDS = %i[username email firstName lastName].freeze + def get_users attributes, page, size, order_by, _ = settings_params(LinkedData::Models::User) query = User.where.include(attributes) if params['search'] - filter = Goo::Filter.new(:username).regex(params['search']) - query = query.filter(filter) + query = query.filter(user_search_filter(params['search'])) end query = query.order_by(order_by || { username: :asc }) @@ -18,6 +19,15 @@ def get_users query.all end + def user_search_filter(term) + field, *remaining_fields = USER_SEARCH_FIELDS + filter = Goo::Filter.new(field).regex(term) + remaining_fields.each do |search_field| + filter = filter.or(Goo::Filter.new(search_field).regex(term)) + end + filter + end + def filter_for_user_onts(obj) return obj unless obj.is_a?(Enumerable) return obj unless env["REMOTE_USER"] diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb index b7e05de0d..9924309ed 100644 --- a/test/controllers/test_users_controller.rb +++ b/test/controllers/test_users_controller.rb @@ -10,6 +10,17 @@ def before_suite User.new(username: username, email: "#{username}@example.org", password: "pass_word").save end + search_users = [ + { username: 'username_marker_account', email: 'search@example.org', firstName: 'Username', lastName: 'Search' }, + { username: 'email_account', email: 'mailmarker@example.org', firstName: 'Email', lastName: 'Search' }, + { username: 'first_name_account', email: 'search@example.org', firstName: 'given_marker', lastName: 'Search' }, + { username: 'last_name_account', email: 'search@example.org', firstName: 'Last', lastName: 'family_marker' } + ] + + @@users.concat(search_users.map do |user_params| + User.new(user_params.merge(password: 'pass_word')).save + end) + # Test data @@username = "test_user" end @@ -60,6 +71,50 @@ def test_all_users_include_all_is_paged assert users_page["collection"].all? { |u| u.key?("created") } end + def test_search_users_by_username + users_page = search_users('username_marker') + usernames = users_page['collection'].map { |user| user['username'] } + + assert_equal ['username_marker_account'], usernames + assert_equal 1, users_page['totalCount'] + assert_equal 1, users_page['pageCount'] + end + + def test_search_users_by_email + users_page = search_users('mailmarker') + usernames = users_page['collection'].map { |user| user['username'] } + + assert_equal ['email_account'], usernames + assert_equal 1, users_page['totalCount'] + assert_equal 1, users_page['pageCount'] + end + + def test_search_users_by_first_name + users_page = search_users('given_marker') + usernames = users_page['collection'].map { |user| user['username'] } + + assert_equal ['first_name_account'], usernames + assert_equal 1, users_page['totalCount'] + assert_equal 1, users_page['pageCount'] + end + + def test_search_users_by_last_name + users_page = search_users('family_marker') + usernames = users_page['collection'].map { |user| user['username'] } + + assert_equal ['last_name_account'], usernames + assert_equal 1, users_page['totalCount'] + assert_equal 1, users_page['pageCount'] + end + + def test_search_users_no_match + users_page = search_users('not_a_search_match') + + assert_equal [], users_page['collection'] + assert_equal 0, users_page['totalCount'] + assert_equal 0, users_page['pageCount'] + end + def test_single_user user = 'fred' get "/users/#{user}" @@ -243,6 +298,12 @@ def _delete_user(username) LinkedData::Models::User.find(@@username).first&.delete end + def search_users(term) + get '/users', search: term, pagesize: 100 + assert last_response.ok? + MultiJson.load(last_response.body) + end + def _create_admin_user(apikey: nil) user = {email: "#{@@username}@example.org", password: "pass_the_word", role: ['ADMINISTRATOR']} _delete_user(@@username) From ae6eed3e0ee55897a3d01a6350fcf2e0c3cdc916 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Wed, 13 May 2026 16:44:42 -0700 Subject: [PATCH 156/173] Preserve username-only user search default --- helpers/users_helper.rb | 19 ++++++++++++++++++- test/controllers/test_users_controller.rb | 23 +++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index 544d093af..d7c62ebca 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -4,6 +4,7 @@ module Sinatra module Helpers module UsersHelper USER_SEARCH_FIELDS = %i[username email firstName lastName].freeze + DEFAULT_USER_SEARCH_FIELDS = %i[username].freeze def get_users attributes, page, size, order_by, _ = settings_params(LinkedData::Models::User) @@ -20,7 +21,7 @@ def get_users end def user_search_filter(term) - field, *remaining_fields = USER_SEARCH_FIELDS + field, *remaining_fields = user_search_fields filter = Goo::Filter.new(field).regex(term) remaining_fields.each do |search_field| filter = filter.or(Goo::Filter.new(search_field).regex(term)) @@ -28,6 +29,22 @@ def user_search_filter(term) filter end + def user_search_fields + return DEFAULT_USER_SEARCH_FIELDS if params['search_fields'].blank? + + fields = params['search_fields'].split(',').map(&:strip).reject(&:empty?).map(&:to_sym) + return DEFAULT_USER_SEARCH_FIELDS if fields.empty? + + unknown_fields = fields - USER_SEARCH_FIELDS + unless unknown_fields.empty? + unsupported_fields = unknown_fields.join(', ') + allowed_fields = USER_SEARCH_FIELDS.join(', ') + error 400, "Unsupported search_fields: #{unsupported_fields}. Allowed fields: #{allowed_fields}" + end + + fields + end + def filter_for_user_onts(obj) return obj unless obj.is_a?(Enumerable) return obj unless env["REMOTE_USER"] diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb index 9924309ed..277cc88a8 100644 --- a/test/controllers/test_users_controller.rb +++ b/test/controllers/test_users_controller.rb @@ -80,8 +80,16 @@ def test_search_users_by_username assert_equal 1, users_page['pageCount'] end - def test_search_users_by_email + def test_search_users_defaults_to_username_only users_page = search_users('mailmarker') + + assert_equal [], users_page['collection'] + assert_equal 0, users_page['totalCount'] + assert_equal 0, users_page['pageCount'] + end + + def test_search_users_by_email + users_page = search_users('mailmarker', search_fields: 'username,email,firstName,lastName') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['email_account'], usernames @@ -90,7 +98,7 @@ def test_search_users_by_email end def test_search_users_by_first_name - users_page = search_users('given_marker') + users_page = search_users('given_marker', search_fields: 'username,email,firstName,lastName') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['first_name_account'], usernames @@ -99,7 +107,7 @@ def test_search_users_by_first_name end def test_search_users_by_last_name - users_page = search_users('family_marker') + users_page = search_users('family_marker', search_fields: 'username,email,firstName,lastName') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['last_name_account'], usernames @@ -108,7 +116,7 @@ def test_search_users_by_last_name end def test_search_users_no_match - users_page = search_users('not_a_search_match') + users_page = search_users('not_a_search_match', search_fields: 'username,email,firstName,lastName') assert_equal [], users_page['collection'] assert_equal 0, users_page['totalCount'] @@ -298,8 +306,11 @@ def _delete_user(username) LinkedData::Models::User.find(@@username).first&.delete end - def search_users(term) - get '/users', search: term, pagesize: 100 + def search_users(term, search_fields: nil) + query_params = { search: term, pagesize: 100 } + query_params[:search_fields] = search_fields if search_fields + + get '/users', query_params assert last_response.ok? MultiJson.load(last_response.body) end From 98a65290b9b7d285478ddd6c5f6c95d388a8043d Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Thu, 14 May 2026 14:29:10 -0700 Subject: [PATCH 157/173] Update search collection test for bootstrap collections Expect the admin search collections endpoint to report the physical Solr bootstrap collections, term_search_bootstrap and property_search_bootstrap, while allowing the stable term_search and property_search aliases as additional entries. --- test/controllers/test_search_models_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/test_search_models_controller.rb b/test/controllers/test_search_models_controller.rb index c065e1779..149b7f535 100644 --- a/test/controllers/test_search_models_controller.rb +++ b/test/controllers/test_search_models_controller.rb @@ -18,8 +18,8 @@ def test_show_all_collection get '/admin/search/collections' assert last_response.ok? res = MultiJson.load(last_response.body) - required = %w[ontology_data ontology_metadata property_search term_search] - allowed_extra = %w[term_search test_solr] + required = %w[ontology_data ontology_metadata property_search_bootstrap term_search_bootstrap] + allowed_extra = %w[property_search term_search test_solr] collections = res["collections"] assert_empty required - collections assert_empty collections - (required + allowed_extra) From 90ec0f1857777575fcc4c9bb913d452f48f57d34 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Thu, 14 May 2026 14:37:41 -0700 Subject: [PATCH 158/173] Gemfile.lock update --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d783492c9..d4d23add4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 2cd237f26202649e4d5cc569aac6272b8448858c + revision: 13f5497873bb9c3b98102977091be63191892de0 branch: feature/solrcloud-alias-indexing-codex specs: goo (0.0.2) @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 7755a51ce891763a0ba174813796df116abca8a9 + revision: 5243ea8db4302ca756c66bf50233e88606830326 branch: develop specs: ncbo_annotator (0.0.1) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: cba1e427240f3909789f263f2105a35f50423176 + revision: dade3889c1c20580cbed21a3136c42a94788f00a branch: feature/solrcloud-alias-indexing-codex specs: ncbo_cron (0.0.1) @@ -55,7 +55,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 2cce61a8e0db96fed9a2a8c4c5b585c385cd8a2c + revision: 722a70afe43daea2be96ba46850d6c917e9d4132 branch: develop specs: ncbo_ontology_recommender (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 8d5090aeeb78d6cd2bf5133ff926d0c1bac44f94 + revision: 38237da4b45f11ec35662d634c62f800b0750fe2 branch: feature/solrcloud-alias-indexing-codex specs: ontologies_linked_data (0.0.1) From 0e2c21b2be3ab77c284293755b662a7f8cef9035 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Fri, 15 May 2026 15:08:17 -0700 Subject: [PATCH 159/173] Support all user search fields shortcut --- helpers/users_helper.rb | 13 ++++++++++++- test/controllers/test_users_controller.rb | 14 ++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index d7c62ebca..0f3a5d7ca 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -5,6 +5,7 @@ module Helpers module UsersHelper USER_SEARCH_FIELDS = %i[username email firstName lastName].freeze DEFAULT_USER_SEARCH_FIELDS = %i[username].freeze + ALL_USER_SEARCH_FIELDS = 'all' def get_users attributes, page, size, order_by, _ = settings_params(LinkedData::Models::User) @@ -32,9 +33,19 @@ def user_search_filter(term) def user_search_fields return DEFAULT_USER_SEARCH_FIELDS if params['search_fields'].blank? - fields = params['search_fields'].split(',').map(&:strip).reject(&:empty?).map(&:to_sym) + fields = params['search_fields'].split(',').map(&:strip).reject(&:empty?) return DEFAULT_USER_SEARCH_FIELDS if fields.empty? + return USER_SEARCH_FIELDS if fields == [ALL_USER_SEARCH_FIELDS] + + if fields.include?(ALL_USER_SEARCH_FIELDS) + error_message = "Unsupported search_fields: #{params['search_fields']}. " + error_message += 'Use all by itself or list individual fields' + error 400, error_message + end + + fields = fields.map(&:to_sym) + unknown_fields = fields - USER_SEARCH_FIELDS unless unknown_fields.empty? unsupported_fields = unknown_fields.join(', ') diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb index 277cc88a8..aac840299 100644 --- a/test/controllers/test_users_controller.rb +++ b/test/controllers/test_users_controller.rb @@ -89,7 +89,7 @@ def test_search_users_defaults_to_username_only end def test_search_users_by_email - users_page = search_users('mailmarker', search_fields: 'username,email,firstName,lastName') + users_page = search_users('mailmarker', search_fields: 'all') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['email_account'], usernames @@ -98,7 +98,7 @@ def test_search_users_by_email end def test_search_users_by_first_name - users_page = search_users('given_marker', search_fields: 'username,email,firstName,lastName') + users_page = search_users('given_marker', search_fields: 'all') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['first_name_account'], usernames @@ -107,7 +107,7 @@ def test_search_users_by_first_name end def test_search_users_by_last_name - users_page = search_users('family_marker', search_fields: 'username,email,firstName,lastName') + users_page = search_users('family_marker', search_fields: 'all') usernames = users_page['collection'].map { |user| user['username'] } assert_equal ['last_name_account'], usernames @@ -116,13 +116,19 @@ def test_search_users_by_last_name end def test_search_users_no_match - users_page = search_users('not_a_search_match', search_fields: 'username,email,firstName,lastName') + users_page = search_users('not_a_search_match', search_fields: 'all') assert_equal [], users_page['collection'] assert_equal 0, users_page['totalCount'] assert_equal 0, users_page['pageCount'] end + def test_search_users_rejects_all_with_other_fields + get '/users', search: 'mailmarker', search_fields: 'all,email' + + assert_equal 400, last_response.status + end + def test_single_user user = 'fred' get "/users/#{user}" From d4e7165e4bfd739b833adacb0e7f4d185dca6920 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Mon, 18 May 2026 18:08:48 -0700 Subject: [PATCH 160/173] Update Solr alias dependency revisions Point the API stack at the latest GOO and related Solr alias commits, including the GOO test cleanup that prevents leaked search collections from breaking API collection assertions. --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d4d23add4..0d926636c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 13f5497873bb9c3b98102977091be63191892de0 + revision: b89adf087b04f9fa58d8fbd1181767cbf03d6ae1 branch: feature/solrcloud-alias-indexing-codex specs: goo (0.0.2) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: dade3889c1c20580cbed21a3136c42a94788f00a + revision: 65fc29eb2228cc2e484c4179fd146248ff0e671c branch: feature/solrcloud-alias-indexing-codex specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 38237da4b45f11ec35662d634c62f800b0750fe2 + revision: 6bc0969076e02ed416f87d3dadf1d6da0946fa78 branch: feature/solrcloud-alias-indexing-codex specs: ontologies_linked_data (0.0.1) From 8906ab2a629c8827da26716766352fd49e795b67 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 19 May 2026 12:58:36 -0700 Subject: [PATCH 161/173] Skip minitest reporters in RubyMine --- test/test_case.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_case.rb b/test/test_case.rb index 0bffc0221..5a7aa7ad4 100644 --- a/test/test_case.rb +++ b/test/test_case.rb @@ -29,7 +29,11 @@ require 'oj' require 'json-schema' require 'minitest/reporters' -Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new(:color => true), Minitest::Reporters::MeanTimeReporter.new] +unless ENV['RM_INFO'] + Minitest::Reporters.use! [ + Minitest::Reporters::SpecReporter.new(color: true), + Minitest::Reporters::MeanTimeReporter.new] +end MAX_TEST_REDIS_SIZE = 10_000 # Check to make sure you want to run if not pointed at localhost From a2b2284f89bf521ad2f80eeac7eaaa3bd54d5dae Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 19 May 2026 13:25:44 -0700 Subject: [PATCH 162/173] Fix some RuboCop warnings --- helpers/users_helper.rb | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index 0f3a5d7ca..04481a0fd 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -5,7 +5,7 @@ module Helpers module UsersHelper USER_SEARCH_FIELDS = %i[username email firstName lastName].freeze DEFAULT_USER_SEARCH_FIELDS = %i[username].freeze - ALL_USER_SEARCH_FIELDS = 'all' + ALL_USER_SEARCH_FIELDS = 'all'.freeze def get_users attributes, page, size, order_by, _ = settings_params(LinkedData::Models::User) @@ -58,14 +58,14 @@ def user_search_fields def filter_for_user_onts(obj) return obj unless obj.is_a?(Enumerable) - return obj unless env["REMOTE_USER"] - return obj if env["REMOTE_USER"].customOntology.empty? - return obj if params["ignore_custom_ontologies"] + return obj unless env['REMOTE_USER'] + return obj if env['REMOTE_USER'].customOntology.empty? + return obj if params['ignore_custom_ontologies'] - user = env["REMOTE_USER"] + user = env['REMOTE_USER'] if obj.first.is_a?(LinkedData::Models::Ontology) - obj = obj.select {|o| user.custom_ontology_id_set.include?(o.id.to_s)} + obj = obj.select { |o| user.custom_ontology_id_set.include?(o.id.to_s) } end obj @@ -73,7 +73,7 @@ def filter_for_user_onts(obj) def send_reset_token(email, username) user = LinkedData::Models::User.where(email: email, username: username).include(LinkedData::Models::User.attributes).first - error 404, "User not found" unless user + error 404, 'User not found' unless user reset_token = token(36) user.resetToken = reset_token user.resetTokenExpireTime = Time.now.to_i + 1.hours.to_i @@ -84,22 +84,22 @@ def send_reset_token(email, username) end def token(len) - chars = ("a".."z").to_a + ("A".."Z").to_a + ("1".."9").to_a - token = "" - 1.upto(len) { |i| token << chars[rand(chars.size-1)] } + chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('1'..'9').to_a + token = '' + 1.upto(len) { |i| token << chars[rand(chars.size - 1)] } token end def reset_password(email, username, token) user = LinkedData::Models::User.where(email: email, username: username).include(User.goo_attrs_to_load(includes_param) + [:resetToken, :passwordHash, :resetTokenExpireTime]).first - error 404, "User not found" unless user + error 404, 'User not found' unless user user.show_apikey = true token_accepted = token.eql?(user.resetToken) if token_accepted - error 401, "Invalid password reset token" if user.resetTokenExpireTime.nil? - error 401, "The password reset token expired" if user.resetTokenExpireTime < Time.now.to_i + error 401, 'Invalid password reset token' if user.resetTokenExpireTime.nil? + error 401, 'The password reset token expired' if user.resetTokenExpireTime < Time.now.to_i user.resetToken = nil user.resetTokenExpireTime = nil user.save(override_security: true) if user.valid? @@ -110,20 +110,20 @@ def reset_password(email, username, token) end def oauth_authenticate(params) - access_token = params["access_token"] - provider = params["token_provider"] + access_token = params['access_token'] + provider = params['token_provider'] user = LinkedData::Models::User.oauth_authenticate(access_token, provider) - error 401, "Access token invalid"if user.nil? + error 401, 'Access token invalid' if user.nil? user end def login_password_authenticate(params) - user_id = params["user"] - user_password = params["password"] + user_id = params['user'] + user_password = params['password'] user = User.find(user_id).include(User.goo_attrs_to_load(includes_param) + [:passwordHash]).first authenticated = false authenticated = user.authenticate(user_password) unless user.nil? - error 401, "Username/password combination invalid" unless authenticated + error 401, 'Username/password combination invalid' unless authenticated user end From fed67fa9a7429acb451b832bad995a2eb6ecc302 Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 19 May 2026 13:29:06 -0700 Subject: [PATCH 163/173] Ignore Serena project metadata --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 45340ce35..4a83fe5b6 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,9 @@ test/data/ontology_files/repo/**/* # Claude Code .claude/ +# Serena +.serena/ + *.swp config/environments/console.rb From 77e1ac05c33b7ee2ba11c1efd97ac39054f07a39 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 19 May 2026 13:39:56 -0700 Subject: [PATCH 164/173] Update API Solr alias dependency revisions Point the API stack at the latest GOO, OLD, and ncbo_cron commits for configurable Solr alias bootstrap migration. --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0d926636c..ff28be103 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: b89adf087b04f9fa58d8fbd1181767cbf03d6ae1 + revision: ceb7598cca8e869b48611bb09b4fb28d21590ec9 branch: feature/solrcloud-alias-indexing-codex specs: goo (0.0.2) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 65fc29eb2228cc2e484c4179fd146248ff0e671c + revision: a0bf1225d4140297fdebcd1f38bfb235fc8ce88e branch: feature/solrcloud-alias-indexing-codex specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 6bc0969076e02ed416f87d3dadf1d6da0946fa78 + revision: 55c4603029aede943af7ada1806d76b621899dd4 branch: feature/solrcloud-alias-indexing-codex specs: ontologies_linked_data (0.0.1) From e6321dfa4c4852912c2836416f70a2fd46ae2e44 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 19 May 2026 13:42:11 -0700 Subject: [PATCH 165/173] Update API read-only alias dependency revisions Point API dependency locks at the OLD/ncbo_cron commits that keep the Solr alias status command read-only. --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ff28be103..5d7157577 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: a0bf1225d4140297fdebcd1f38bfb235fc8ce88e + revision: 3d1a4cf89b045037a2cbd3eb321ec432c7f88a15 branch: feature/solrcloud-alias-indexing-codex specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 55c4603029aede943af7ada1806d76b621899dd4 + revision: e152f6363587a579b2141484bf7d1053b1072642 branch: feature/solrcloud-alias-indexing-codex specs: ontologies_linked_data (0.0.1) From 1088ecd467f668793040aeb83e76b27f092e7c8a Mon Sep 17 00:00:00 2001 From: Jennifer Vendetti Date: Tue, 19 May 2026 13:44:32 -0700 Subject: [PATCH 166/173] Refactor user search field parsing --- helpers/users_helper.rb | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb index 04481a0fd..06effae04 100644 --- a/helpers/users_helper.rb +++ b/helpers/users_helper.rb @@ -31,29 +31,37 @@ def user_search_filter(term) end def user_search_fields - return DEFAULT_USER_SEARCH_FIELDS if params['search_fields'].blank? - - fields = params['search_fields'].split(',').map(&:strip).reject(&:empty?) + fields = requested_user_search_fields return DEFAULT_USER_SEARCH_FIELDS if fields.empty? + validate_all_user_search_fields!(fields) return USER_SEARCH_FIELDS if fields == [ALL_USER_SEARCH_FIELDS] - if fields.include?(ALL_USER_SEARCH_FIELDS) - error_message = "Unsupported search_fields: #{params['search_fields']}. " - error_message += 'Use all by itself or list individual fields' - error 400, error_message - end - fields = fields.map(&:to_sym) + validate_known_user_search_fields!(fields) + fields + end + + def requested_user_search_fields + params['search_fields'].to_s.split(',').map(&:strip).reject(&:empty?) + end + + def validate_all_user_search_fields!(fields) + return unless fields.include?(ALL_USER_SEARCH_FIELDS) && fields != [ALL_USER_SEARCH_FIELDS] + + error_message = "Unsupported search_fields: #{params['search_fields']}. " + error_message += 'Use all by itself or list individual fields' + error 400, error_message + end + + def validate_known_user_search_fields!(fields) unknown_fields = fields - USER_SEARCH_FIELDS - unless unknown_fields.empty? - unsupported_fields = unknown_fields.join(', ') - allowed_fields = USER_SEARCH_FIELDS.join(', ') - error 400, "Unsupported search_fields: #{unsupported_fields}. Allowed fields: #{allowed_fields}" - end + return if unknown_fields.empty? - fields + unsupported_fields = unknown_fields.join(', ') + allowed_fields = USER_SEARCH_FIELDS.join(', ') + error 400, "Unsupported search_fields: #{unsupported_fields}. Allowed fields: #{allowed_fields}" end def filter_for_user_onts(obj) From 95124b0caa9dbff019c771e7b7e8c8aabf597270 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 19 May 2026 16:19:43 -0700 Subject: [PATCH 167/173] Gemfile & Gemfile.lock update --- Gemfile | 6 +++--- Gemfile.lock | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index ab7f32289..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'feature/solrcloud-alias-indexing-codex' +gem 'goo', github: 'ncbo/goo', branch: 'development' gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'feature/solrcloud-alias-indexing-codex' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'feature/solrcloud-alias-indexing-codex' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index d93eacef9..067e81ae8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: ceb7598cca8e869b48611bb09b4fb28d21590ec9 - branch: feature/solrcloud-alias-indexing-codex + revision: 0187c6c0ba3871fa8b67055c1a1adfdea38b2189 + branch: development specs: goo (0.0.2) addressable (~> 2.8) @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 3d1a4cf89b045037a2cbd3eb321ec432c7f88a15 - branch: feature/solrcloud-alias-indexing-codex + revision: 91fb6b34e6f0bb827a6da721b083640b823d1083 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: e152f6363587a579b2141484bf7d1053b1072642 - branch: feature/solrcloud-alias-indexing-codex + revision: bd01bf6002df9a9fd8070f0db4f3a833ac1b39ad + branch: develop specs: ontologies_linked_data (0.0.1) activesupport From 1884b1d2830f327f240c93a2d8b0692b102c809b Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Fri, 22 May 2026 13:42:05 -0700 Subject: [PATCH 168/173] Gemfile & Gemfile.lock update --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 26f1d7452..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 497b232c3..f9802e2ff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: ee72f43daa37f02362da1b747f037c442cfbf112 - branch: main + revision: 0187c6c0ba3871fa8b67055c1a1adfdea38b2189 + branch: development specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: b216bdde2de471fc0f851556ffa2327333516e79 - branch: master + revision: 5243ea8db4302ca756c66bf50233e88606830326 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 18a6c183d5dd59b3adda58af90bab334fb911537 - branch: master + revision: 91fb6b34e6f0bb827a6da721b083640b823d1083 + branch: develop specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: e63da099a5d69cf08d2c1c0d58b2f80bd5d41bb0 - branch: master + revision: 722a70afe43daea2be96ba46850d6c917e9d4132 + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 32023829506089164a27da1e6aa05b901a019079 - branch: master + revision: d4492a5cf76d78e74b677cc3f05c97dcbd53ccb7 + branch: develop specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: main + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From 814a52710123116492a067c07b7f44842863f48f Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Fri, 22 May 2026 15:27:43 -0700 Subject: [PATCH 169/173] Gemfile & Gemfile.lock update --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 9867a4b00..26f1d7452 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index f9802e2ff..9e66345f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 0187c6c0ba3871fa8b67055c1a1adfdea38b2189 - branch: development + revision: c956c8efe6490973a3b498fc4bfca072cefacec5 + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 5243ea8db4302ca756c66bf50233e88606830326 - branch: develop + revision: b216bdde2de471fc0f851556ffa2327333516e79 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 91fb6b34e6f0bb827a6da721b083640b823d1083 - branch: develop + revision: 3f1a56aabc4327588545c22541f3c0eb69106cce + branch: master specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 722a70afe43daea2be96ba46850d6c917e9d4132 - branch: develop + revision: e63da099a5d69cf08d2c1c0d58b2f80bd5d41bb0 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: d4492a5cf76d78e74b677cc3f05c97dcbd53ccb7 - branch: develop + revision: 0a8ef786c6dcd8bbcd9a3a8c5e9f5839d510eb1a + branch: master specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: development + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) From 7dad03095e832a5cb681929f4c3974ab26e2e638 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 26 May 2026 17:35:41 -0700 Subject: [PATCH 170/173] Gemfile.lock update --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f9802e2ff..76851b406 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 0187c6c0ba3871fa8b67055c1a1adfdea38b2189 + revision: 28329ce66ca724ba3652576938e9dc219ca496bf branch: development specs: goo (0.0.2) @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 91fb6b34e6f0bb827a6da721b083640b823d1083 + revision: b8a2ac9d6457a7b4418103d2206f478e73c9ee16 branch: develop specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: d4492a5cf76d78e74b677cc3f05c97dcbd53ccb7 + revision: b30f9f9ec54d3daa0d0b43ad4cecc73588713dff branch: develop specs: ontologies_linked_data (0.0.1) From 3754fffa2ffa7751f940e316a80993b112f5dfd0 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 26 May 2026 18:03:45 -0700 Subject: [PATCH 171/173] Gemfile.lock update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 76851b406..bda52a6b5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,7 +37,7 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: b8a2ac9d6457a7b4418103d2206f478e73c9ee16 + revision: 5b54b269fdf7f0ced79a86700b7649a1f38df31c branch: develop specs: ncbo_cron (0.0.1) @@ -66,7 +66,7 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: b30f9f9ec54d3daa0d0b43ad4cecc73588713dff + revision: 1d0acc3e0e91fb6e0c1ffb393a0e5fdbe481d6e2 branch: develop specs: ontologies_linked_data (0.0.1) From d18ccba63d5d23d3941f5ab479842aca280b6766 Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 26 May 2026 18:19:46 -0700 Subject: [PATCH 172/173] Gemfile & Gemfile.lock update --- Gemfile | 12 +++++----- Gemfile.lock | 66 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/Gemfile b/Gemfile index 26f1d7452..9867a4b00 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'main' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' +gem 'goo', github: 'ncbo/goo', branch: 'development' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index d919f78f5..de50a3969 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: b216bdde2de471fc0f851556ffa2327333516e79 - branch: master + revision: 5243ea8db4302ca756c66bf50233e88606830326 + branch: develop specs: ncbo_annotator (0.0.1) goo @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: e63da099a5d69cf08d2c1c0d58b2f80bd5d41bb0 - branch: master + revision: 722a70afe43daea2be96ba46850d6c917e9d4132 + branch: develop specs: ncbo_ontology_recommender (0.0.1) goo @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: main + branch: development specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2) @@ -152,7 +152,7 @@ GEM bigdecimal (4.1.2) builder (3.3.0) byebug (12.0.0) - capistrano (3.20.0) + capistrano (3.20.1) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) @@ -180,21 +180,27 @@ GEM ed25519 (1.4.0) et-orbi (1.4.0) tzinfo - faraday (2.14.1) + faraday (2.14.2) faraday-net_http (>= 2.0, < 3.5) json logger faraday-follow_redirects (0.5.0) faraday (>= 1, < 3) - faraday-net_http (3.4.2) + faraday-net_http (3.4.3) net-http (~> 0.5) faraday-retry (2.4.0) faraday (~> 2.0) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -227,6 +233,7 @@ GEM google-protobuf (3.25.3) google-protobuf (3.25.3-aarch64-linux) google-protobuf (3.25.3-arm64-darwin) + google-protobuf (3.25.3-x86-linux) google-protobuf (3.25.3-x86_64-darwin) google-protobuf (3.25.3-x86_64-linux) googleapis-common-protos (1.8.0) @@ -252,6 +259,9 @@ GEM grpc (1.70.1-arm64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) + grpc (1.70.1-x86-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) grpc (1.70.1-x86_64-darwin) google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) @@ -281,7 +291,7 @@ GEM json-schema (6.2.0) addressable (~> 2.8) bigdecimal (>= 3.1, < 5) - jwt (3.1.2) + jwt (3.2.0) base64 kgio (2.11.4) kramdown (2.5.2) @@ -342,9 +352,9 @@ GEM net-protocol net-ssh (7.3.2) netrc (0.11.0) - newrelic_rpm (10.4.0) + newrelic_rpm (10.5.0) logger - oj (3.17.0) + oj (3.17.1) bigdecimal (>= 3.0) ostruct (>= 0.2) omni_logger (0.1.4) @@ -431,7 +441,7 @@ GEM rsolr (2.6.0) builder (>= 2.1.2) faraday (>= 0.9, < 3, != 2.0.0) - rubocop (1.86.1) + rubocop (1.86.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -514,10 +524,18 @@ GEM PLATFORMS aarch64-linux aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl arm64-darwin ruby + x86-linux + x86-linux-gnu + x86-linux-musl x86_64-darwin x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES activesupport @@ -598,7 +616,7 @@ CHECKSUMS bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e - capistrano (3.20.0) sha256=0113e58dda99add0342e56a244f664734c59f442c5ed734f5303b0b559b479c9 + capistrano (3.20.1) sha256=b0d54ba5cf49bb194998bf6b427e889aa36ed05f545ecf7cc37acb9d529e9ae9 capistrano-bundler (2.2.0) sha256=47b4cf2ea17ea132bb0a5cabc5663443f5190a54f4da5b322d04e1558ff1468c capistrano-locally (0.3.0) sha256=ad44252f19641e8dd980f7cb0241e9ac11919b1f4cbdb642d272a6d0edcb84eb capistrano-rbenv (2.2.0) sha256=3c8f39b7c624f3806630dcb475484bb3579aef07a40efe85089d83f64b0c35f5 @@ -614,15 +632,21 @@ CHECKSUMS drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 ed25519 (1.4.0) sha256=16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506 et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc - faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c + faraday (2.14.2) sha256=73ccb9994a9e8648f010e32eca2ae82e41c57860aa10932cda29418b9e0223ad faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad - faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c + faraday-net_http (3.4.3) sha256=9db13becec9312f345a769eeeecf9049c9287d54c0ae053d7235228993a4eec1 faraday-retry (2.4.0) sha256=7b79c48fb7e56526faf247b12d94a680071ff40c9fda7cf1ec1549439ad11ebe ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 + ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 + ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf + ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d + ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e fugit (1.12.1) sha256=5898f478ede9b415f0804e42b8f3fd53f814bd85eebffceebdbc34e1107aaf68 gapic-common (1.1.0) sha256=3270ab3c5135012a4ab4d8848f945cf35014192f24504cdb40c66fc67f1beaa3 get_process_mem (0.2.7) sha256=4afd3c3641dd6a817c09806c7d6d509d8a9984512ac38dea8b917426bbf77eba @@ -636,6 +660,7 @@ CHECKSUMS google-protobuf (3.25.3) sha256=39bd97cbc7631905e76cdf8f1bf3dda1c3d05200d7e23f575aced78930fbddd6 google-protobuf (3.25.3-aarch64-linux) sha256=5ea9d20d60e5d3bef8d881b426946345e5ac6cf4779ac81cd900e45f40567243 google-protobuf (3.25.3-arm64-darwin) sha256=c42cddd21c4f09fd756fe0efd70ab6c8006dd67ffbb04e99fe7310f49923d18c + google-protobuf (3.25.3-x86-linux) sha256=7a0e74f14affbce6024595cdb55e7e8c5a51716f0bb11b103c63cbe3a3a0e348 google-protobuf (3.25.3-x86_64-darwin) sha256=13d27e96e89835f642c444e32414fd50fabc29a125d78760ad067d6536214f02 google-protobuf (3.25.3-x86_64-linux) sha256=ceeba879d9313a2bd0600a97d6fe3cf529a9b37d12ca026f891996c118b7ffb2 googleapis-common-protos (1.8.0) sha256=bfe89cb75d1a8f13e4591d262a20333e145481d803adb74dd13ac0517decdffe @@ -644,6 +669,7 @@ CHECKSUMS grpc (1.70.1) sha256=174594605c96df3caed44a83221665aa6e11f554e56028f89bef82c07ffb83cb grpc (1.70.1-aarch64-linux) sha256=48e0b22b8b96e61ca7054a7fea894a4845498e6bf366b50eff03e588f714ed96 grpc (1.70.1-arm64-darwin) sha256=eeb6758dd58135e4e5fcd78726b9a18d34d7313e41bc81528ff4b3dce65cf525 + grpc (1.70.1-x86-linux) sha256=cb7921614fec4f90f888637736b7ede85305ad94a869f736176f9ebede98c4f1 grpc (1.70.1-x86_64-darwin) sha256=628cb929542c277b6e5f638b6b8575b3bdcde250a2a70bddf8c0be1bf77e6781 grpc (1.70.1-x86_64-linux) sha256=ed12eea749127119c9761a58ba17ce92aadbc35b0b4fa27e4bd8ec84047d63be haml (5.2.2) sha256=6e759246556145642ef832d670fc06f9bd8539159a0e600847a00291dd7aae0c @@ -657,7 +683,7 @@ CHECKSUMS json-canonicalization (0.4.0) sha256=73ea88b68f210d1a09c2116d4cd1ff5a39684c6a409f7ccac70d5b1a426a8bef json-ld (3.2.5) sha256=98b96f1831b0fe9c7d2568a7d43b64f6b8c3f5892d55ccf91640e32a99c273fc json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 - jwt (3.1.2) sha256=af6991f19a6bb4060d618d9add7a66f0eeb005ac0bc017cd01f63b42e122d535 + jwt (3.2.0) sha256=5419b1fe37b1da0982bd07051f573a8b8789ab724c2aa7e785e4784a3ed217d7 kgio (2.11.4) sha256=bda7a2146115998a5b07154e708e0ac02c38dcee7e793c33e2e14f600fdfffc6 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc @@ -692,8 +718,8 @@ CHECKSUMS net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 net-ssh (7.3.2) sha256=65029e213c380e20e5fd92ece663934ab0a0fe888e0cd7cc6a5b664074362dd4 netrc (0.11.0) sha256=de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f - newrelic_rpm (10.4.0) sha256=36e3bc31adc89c3fe2056d1014a4d93b38bb63050050a1a442b35c4559531291 - oj (3.17.0) sha256=5684b2127fb70e650fae90df521b91336ff8e55e2e1011ed80eb0283beac5360 + newrelic_rpm (10.5.0) sha256=93c3d34813a1145705002283d7c32fa9a6b0b8e4fabe2cfbcfc791ee4c2ccd6d + oj (3.17.1) sha256=b00687f10bf68a32bfb633b87624174faf0989a5c96aff2f3f96f992717ce782 omni_logger (0.1.4) sha256=b61596f7d96aa8426929e46c3500558d33e838e1afd7f4735244feb4d082bb3e ontologies_linked_data (0.0.1) ontoportal_testkit (0.1.0) @@ -739,7 +765,7 @@ CHECKSUMS rest-client (2.1.0) sha256=35a6400bdb14fae28596618e312776c158f7ebbb0ccad752ff4fa142bf2747e3 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rsolr (2.6.0) sha256=4b3bcea772cac300562775c20eeddedf63a6b7516a070cb6fbde000b09cfe12b - rubocop (1.86.1) sha256=44415f3f01d01a21e01132248d2fd0867572475b566ca188a0a42133a08d4531 + rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 ruby-xxHash (0.4.0.2) sha256=201d8305ec1bd0bc32abeaecf7b423755dd1f45f4f4d02ef793b6bb71bf20684 @@ -772,4 +798,4 @@ CHECKSUMS webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 BUNDLED WITH - 4.0.7 + 4.0.10 From 214795f0f5d4a441bdf023ef7435a94a2f1a863f Mon Sep 17 00:00:00 2001 From: Michael Dorf Date: Tue, 26 May 2026 18:47:50 -0700 Subject: [PATCH 173/173] Gemfile & Gemfile.lock update --- Gemfile | 12 ++++++------ Gemfile.lock | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 9867a4b00..26f1d7452 100644 --- a/Gemfile +++ b/Gemfile @@ -50,12 +50,12 @@ gem 'rack-contrib' gem 'kramdown' # NCBO gems (can be from a local dev path or from rubygems/git) -gem 'goo', github: 'ncbo/goo', branch: 'development' -gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'development' -gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'develop' -gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'develop' -gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'develop' -gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'develop' +gem 'goo', github: 'ncbo/goo', branch: 'main' +gem 'sparql-client', github: 'ncbo/sparql-client', branch: 'main' +gem 'ncbo_annotator', github: 'ncbo/ncbo_annotator', branch: 'master' +gem 'ncbo_cron', github: 'ncbo/ncbo_cron', branch: 'master' +gem 'ncbo_ontology_recommender', github: 'ncbo/ncbo_ontology_recommender', branch: 'master' +gem 'ontologies_linked_data', github: 'ncbo/ontologies_linked_data', branch: 'master' group :development do gem 'shotgun', github: 'syphax-bouazzouni/shotgun', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index de50a3969..16434b50f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,8 @@ GIT GIT remote: https://github.com/ncbo/goo.git - revision: 28329ce66ca724ba3652576938e9dc219ca496bf - branch: development + revision: 84ef6a293f32b08ae5e021b514b8e8ea23685036 + branch: main specs: goo (0.0.2) addressable (~> 2.8) @@ -26,8 +26,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_annotator.git - revision: 5243ea8db4302ca756c66bf50233e88606830326 - branch: develop + revision: b216bdde2de471fc0f851556ffa2327333516e79 + branch: master specs: ncbo_annotator (0.0.1) goo @@ -37,8 +37,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_cron.git - revision: 5b54b269fdf7f0ced79a86700b7649a1f38df31c - branch: develop + revision: f7239a8664224f729b172416f3b8170a0ec684c8 + branch: master specs: ncbo_cron (0.0.1) dante @@ -55,8 +55,8 @@ GIT GIT remote: https://github.com/ncbo/ncbo_ontology_recommender.git - revision: 722a70afe43daea2be96ba46850d6c917e9d4132 - branch: develop + revision: e63da099a5d69cf08d2c1c0d58b2f80bd5d41bb0 + branch: master specs: ncbo_ontology_recommender (0.0.1) goo @@ -66,8 +66,8 @@ GIT GIT remote: https://github.com/ncbo/ontologies_linked_data.git - revision: 1d0acc3e0e91fb6e0c1ffb393a0e5fdbe481d6e2 - branch: develop + revision: 24935f63fd311ee5002dd7a0b597b6ae9a081ace + branch: master specs: ontologies_linked_data (0.0.1) activesupport @@ -89,7 +89,7 @@ GIT GIT remote: https://github.com/ncbo/sparql-client.git revision: 2ac20b217bb7ad2b11305befe0ee77d75e44eac5 - branch: development + branch: main specs: sparql-client (3.2.2) net-http-persistent (~> 4.0, >= 4.0.2)