diff --git a/Gemfile b/Gemfile
index 127ad02f..49c8357e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -44,12 +44,12 @@ 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', git: 'https://github.com/ontoportal-lirmm/goo.git', branch: 'development'
+gem 'goo', git: 'https://github.com/ontoportal-lirmm/goo.git', branch: 'master'
gem 'ncbo_annotator', git: 'https://github.com/ontoportal-lirmm/ncbo_annotator.git', branch: 'master'
gem 'ncbo_cron', git: 'https://github.com/ontoportal-lirmm/ncbo_cron.git', branch: 'master'
gem 'ncbo_ontology_recommender', git: 'https://github.com/ncbo/ncbo_ontology_recommender.git', branch: 'master'
gem 'sparql-client', github: 'ontoportal-lirmm/sparql-client', branch: 'master'
-gem 'ontologies_linked_data', git: 'https://github.com/ontoportal-lirmm/ontologies_linked_data.git', branch: 'development'
+gem 'ontologies_linked_data', git: 'https://github.com/ontoportal-lirmm/ontologies_linked_data.git', 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
@@ -73,4 +73,5 @@ group :test do
gem 'rack-test'
gem 'simplecov', require: false
gem 'simplecov-cobertura' # for codecov.io
-end
+ gem 'webmock'
+end
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
index fabf3bd7..3428c7b2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/ncbo/ncbo_ontology_recommender.git
- revision: 83e835de368bc9f19da800a477982e0ad770900d
+ revision: 013abea4af3b10910ec661dbb358a4b6cae198a4
branch: master
specs:
ncbo_ontology_recommender (0.0.1)
@@ -11,8 +11,8 @@ GIT
GIT
remote: https://github.com/ontoportal-lirmm/goo.git
- revision: ddb95e427950fde3ac715aec340394208c8166fe
- branch: development
+ revision: 74ea47defc7f6260b045a6c6997bbe6a59c7bf62
+ branch: master
specs:
goo (0.0.2)
addressable (~> 2.8)
@@ -53,8 +53,8 @@ GIT
GIT
remote: https://github.com/ontoportal-lirmm/ontologies_linked_data.git
- revision: 4c89c8346766d23e09b24c8e29750bf3a91e6b53
- branch: development
+ revision: 80a331d053ea04397a903452288c2186822c340c
+ branch: master
specs:
ontologies_linked_data (0.0.1)
activesupport
@@ -105,14 +105,15 @@ GEM
multi_json (~> 1.0)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
- airbrussh (1.4.2)
+ airbrussh (1.5.0)
sshkit (>= 1.6.1, != 1.7.0)
backports (3.24.1)
- bcrypt (3.1.19)
+ base64 (0.2.0)
+ bcrypt (3.1.20)
bcrypt_pbkdf (1.1.0)
bigdecimal (1.4.2)
builder (3.2.4)
- capistrano (3.17.3)
+ capistrano (3.18.0)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
@@ -126,13 +127,14 @@ GEM
sshkit (~> 1.3)
coderay (1.1.3)
concurrent-ruby (1.2.2)
+ crack (0.4.5)
+ rexml
cube-ruby (0.0.3)
dante (0.2.0)
- date (3.3.3)
+ date (3.3.4)
declarative (0.0.20)
docile (1.4.0)
- domain_name (0.5.20190701)
- unf (>= 0.0.5, < 1.0.0)
+ domain_name (0.6.20231109)
ed25519 (1.3.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
@@ -157,12 +159,12 @@ GEM
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
- ffi (1.15.5)
+ ffi (1.16.3)
get_process_mem (0.2.7)
ffi (~> 1.0)
google-apis-analytics_v3 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
- google-apis-core (0.11.1)
+ google-apis-core (0.11.2)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -171,30 +173,30 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
- googleauth (1.7.0)
+ googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
- memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
haml (5.2.2)
temple (>= 0.8.0)
tilt
+ hashdiff (1.0.1)
http-accept (1.7.0)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
- json (2.6.3)
+ json (2.7.1)
json-schema (2.8.1)
addressable (>= 2.4)
- json_pure (2.6.3)
+ json_pure (2.7.1)
jwt (2.7.1)
kgio (2.11.4)
- libxml-ruby (4.1.1)
- logger (1.5.3)
+ libxml-ruby (4.1.2)
+ logger (1.6.0)
macaddr (1.7.2)
systemu (~> 2.6.5)
mail (2.8.1)
@@ -202,11 +204,10 @@ GEM
net-imap
net-pop
net-smtp
- memoist (0.16.2)
method_source (1.0.0)
mime-types (3.5.1)
mime-types-data (~> 3.2015)
- mime-types-data (3.2023.0808)
+ mime-types-data (3.2023.1003)
mini_mime (1.1.5)
minitest (4.7.5)
minitest-stub_any_instance (1.0.3)
@@ -215,20 +216,21 @@ GEM
multi_json (1.15.0)
multipart-post (2.3.0)
net-http-persistent (2.9.4)
- net-imap (0.3.7)
+ net-imap (0.4.7)
date
net-protocol
net-pop (0.1.2)
net-protocol
- net-protocol (0.2.1)
+ net-protocol (0.2.2)
timeout
net-scp (4.0.0)
net-ssh (>= 2.6.5, < 8.0.0)
- net-smtp (0.3.3)
+ net-smtp (0.4.0)
net-protocol
net-ssh (7.2.0)
netrc (0.11.0)
- newrelic_rpm (9.4.2)
+ newrelic_rpm (9.6.0)
+ base64
oj (2.18.5)
omni_logger (0.1.4)
logger
@@ -239,13 +241,13 @@ GEM
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
- public_suffix (5.0.3)
+ public_suffix (5.0.4)
rack (1.6.13)
rack-accept (0.4.5)
rack (>= 0.4)
rack-attack (6.6.1)
rack (>= 1.0, < 3)
- rack-cache (1.13.0)
+ rack-cache (1.14.0)
rack (>= 0.4)
rack-cors (1.0.6)
rack (>= 1.6.0)
@@ -268,8 +270,8 @@ GEM
redis-rack-cache (2.2.1)
rack-cache (>= 1.10, < 2)
redis-store (>= 1.6, < 2)
- redis-store (1.9.1)
- redis (>= 4, < 5)
+ redis-store (1.9.2)
+ redis (>= 4, < 6)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
@@ -291,7 +293,7 @@ GEM
rubyzip (2.3.2)
rufus-scheduler (2.0.24)
tzinfo (>= 0.3.22)
- signet (0.17.0)
+ signet (0.18.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
@@ -318,20 +320,17 @@ GEM
rack-test
sinatra (~> 1.4.0)
tilt (>= 1.3, < 3)
- sshkit (1.21.5)
+ sshkit (1.21.6)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
systemu (2.6.5)
- temple (0.10.2)
- tilt (2.2.0)
- timeout (0.4.0)
+ temple (0.10.3)
+ tilt (2.3.0)
+ timeout (0.4.1)
trailblazer-option (0.1.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uber (0.1.0)
- unf (0.1.4)
- unf_ext
- unf_ext (0.0.8.2)
unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
@@ -340,10 +339,15 @@ GEM
unicorn (>= 4, < 7)
uuid (2.3.9)
macaddr (~> 1.0)
+ webmock (3.19.1)
+ addressable (>= 2.8.0)
+ crack (>= 0.3.2)
+ hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
PLATFORMS
x86_64-darwin-21
+ x86_64-darwin-23
x86_64-linux
DEPENDENCIES
@@ -397,6 +401,7 @@ DEPENDENCIES
sparql-client!
unicorn
unicorn-worker-killer
+ webmock
BUNDLED WITH
- 2.3.23
+ 2.4.21
diff --git a/app.rb b/app.rb
index b61fdcbe..46457c86 100644
--- a/app.rb
+++ b/app.rb
@@ -29,6 +29,7 @@
require_relative 'lib/rack/cube_reporter'
require_relative 'lib/rack/param_translator'
require_relative 'lib/rack/slice_detection'
+require_relative 'lib/rack/request_lang'
# Logging setup
require_relative "config/logging"
@@ -146,6 +147,7 @@
use Rack::ParamTranslator
use RequestStore::Middleware
+use Rack::RequestLang
use LinkedData::Security::Authorization
use LinkedData::Security::AccessDenied
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 0f421dec..16bf407a 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -55,6 +55,24 @@
"apikey" => "1cfae05f-9e67-486f-820b-b393dec5764b"
}
}
+ 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/config/solr/property_search/enumsconfig.xml b/config/solr/property_search/enumsconfig.xml
new file mode 100644
index 00000000..72e7b7d3
--- /dev/null
+++ b/config/solr/property_search/enumsconfig.xml
@@ -0,0 +1,12 @@
+
+
+
+ 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
new file mode 100644
index 00000000..ede77425
--- /dev/null
+++ b/config/solr/property_search/mapping-ISOLatin1Accent.txt
@@ -0,0 +1,246 @@
+# 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
new file mode 100644
index 00000000..20824ea6
--- /dev/null
+++ b/config/solr/property_search/schema.xml
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/solr/property_search/solrconfig.xml b/config/solr/property_search/solrconfig.xml
new file mode 100644
index 00000000..771a0f32
--- /dev/null
+++ b/config/solr/property_search/solrconfig.xml
@@ -0,0 +1,1299 @@
+
+
+
+
+
+
+
+
+ 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
new file mode 100644
index 00000000..d9d089e4
--- /dev/null
+++ b/config/solr/solr.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+ ${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
new file mode 100644
index 00000000..72e7b7d3
--- /dev/null
+++ b/config/solr/term_search/enumsconfig.xml
@@ -0,0 +1,12 @@
+
+
+
+ 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
new file mode 100644
index 00000000..ede77425
--- /dev/null
+++ b/config/solr/term_search/mapping-ISOLatin1Accent.txt
@@ -0,0 +1,246 @@
+# 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
new file mode 100644
index 00000000..fa95e127
--- /dev/null
+++ b/config/solr/term_search/schema.xml
@@ -0,0 +1,1222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/solr/term_search/solrconfig.xml b/config/solr/term_search/solrconfig.xml
new file mode 100644
index 00000000..771a0f32
--- /dev/null
+++ b/config/solr/term_search/solrconfig.xml
@@ -0,0 +1,1299 @@
+
+
+
+
+
+
+
+
+ 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/admin_controller.rb b/controllers/admin_controller.rb
index 7ae6d800..747def93 100644
--- a/controllers/admin_controller.rb
+++ b/controllers/admin_controller.rb
@@ -68,7 +68,7 @@ class AdminController < ApplicationController
latest = ont.latest_submission(status: :any)
error 404, "Ontology #{params["acronym"]} contains no submissions" if latest.nil?
check_last_modified(latest)
- latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param))
+ latest.bring(*submission_include_params)
NcboCron::Models::OntologySubmissionParser.new.queue_submission(latest, actions)
halt 204
end
@@ -84,7 +84,7 @@ class AdminController < ApplicationController
latest = ont.latest_submission(status: :any)
end
check_last_modified(latest) if latest
- latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) if latest
+ latest.bring(*submission_include_params) if latest
reply(latest || {})
end
diff --git a/controllers/classes_controller.rb b/controllers/classes_controller.rb
index c8e55bf8..d792c172 100644
--- a/controllers/classes_controller.rb
+++ b/controllers/classes_controller.rb
@@ -262,13 +262,7 @@ def includes_param_check
end
end
- def concept_schemes
- params["concept_schemes"]&.split(',') || []
- end
- def concept_collections
- params["concept_collections"]&.split(',') || []
- end
def request_display(attrs)
diff --git a/controllers/ontologies_controller.rb b/controllers/ontologies_controller.rb
index 99c0ce68..58518420 100644
--- a/controllers/ontologies_controller.rb
+++ b/controllers/ontologies_controller.rb
@@ -38,22 +38,12 @@ class OntologiesController < ApplicationController
else
latest = ont.latest_submission(status: :any)
end
- check_last_modified(latest) if latest
- # When asking to display all metadata, we are using bring_remaining which is more performant than including all metadata (remove this when the query to get metadata will be fixed)
- if latest
- if includes_param.first == :all
- # Bring what we need to display all attr of the submission
- latest.bring_remaining
- latest.bring(*submission_attributes_all)
- else
- includes = OntologySubmission.goo_attrs_to_load(includes_param)
-
- includes << {:contact=>[:name, :email]} if includes.find{|v| v.is_a?(Hash) && v.keys.first.eql?(:contact)}
- latest.bring(*includes)
- end
+ if latest
+ check_last_modified(latest)
+ latest.bring(*submission_include_params)
end
- #remove the whole previous if block and replace by it: latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) if latest
+
reply(latest || {})
end
@@ -63,7 +53,7 @@ class OntologiesController < ApplicationController
patch '/:acronym/latest_submission' do
ont = Ontology.find(params["acronym"]).first
error 422, "You must provide an existing `acronym` to patch" if ont.nil?
-
+
submission = ont.latest_submission(status: :any)
submission.bring(*OntologySubmission.attributes)
diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb
index e2817de9..0068a5f1 100644
--- a/controllers/ontology_submissions_controller.rb
+++ b/controllers/ontology_submissions_controller.rb
@@ -25,20 +25,18 @@ class OntologySubmissionsController < ApplicationController
##
# Display all submissions of an ontology
get do
- ont = Ontology.find(params["acronym"]).include(:acronym).first
+ ont = Ontology.find(params["acronym"]).include(:acronym, :administeredBy, :acl, :viewingRestriction).first
error 422, "Ontology #{params["acronym"]} does not exist" unless ont
check_last_modified_segment(LinkedData::Models::OntologySubmission, [ont.acronym])
- if includes_param.first == :all
- # When asking to display all metadata, we are using bring_remaining which is more performant than including all metadata (remove this when the query to get metadata will be fixed)
- ont.bring(submission_attributes_all)
-
- ont.submissions.each do |sub|
- sub.bring_remaining
- end
- else
- ont.bring(submissions: OntologySubmission.goo_attrs_to_load(includes_param))
- end
- reply ont.submissions.sort {|a,b| b.submissionId.to_i <=> a.submissionId.to_i } # descending order of submissionId
+ check_access(ont)
+ options = {
+ also_include_views: true,
+ status: (params["include_status"] || "ANY"),
+ ontology: params["acronym"]
+ }
+ subs = retrieve_submissions(options)
+
+ reply subs.sort {|a,b| b.submissionId.to_i <=> a.submissionId.to_i } # descending order of submissionId
end
##
@@ -57,7 +55,7 @@ class OntologySubmissionsController < ApplicationController
ont.bring(:submissions)
ont_submission = ont.submission(params["ontology_submission_id"])
error 404, "`submissionId` not found" if ont_submission.nil?
- ont_submission.bring(*OntologySubmission.goo_attrs_to_load(includes_param))
+ ont_submission.bring(*submission_include_params)
reply ont_submission
end
diff --git a/controllers/users_controller.rb b/controllers/users_controller.rb
index 00b6e732..09a1835b 100644
--- a/controllers/users_controller.rb
+++ b/controllers/users_controller.rb
@@ -1,14 +1,17 @@
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
+ user.show_apikey = true unless user.nil?
reply user
end
@@ -20,17 +23,13 @@ class UsersController < ApplicationController
post "/create_reset_password_token" do
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 = 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
##
@@ -42,11 +41,11 @@ class UsersController < ApplicationController
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
- if token.eql?(user.resetToken)
- user.show_apikey = true
+
+ user, token_accepted = reset_password(email, username, token)
+ if token_accepted
reply user
else
error 403, "Password reset not authorized with this token"
@@ -98,12 +97,6 @@ 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
params ||= @params
@@ -111,14 +104,7 @@ def create_user
error 409, "User with username `#{params["username"]}` already exists" unless user.nil?
user = instance_from_params(User, params)
if user.valid?
- user.save
- # Send an email to the administrator to warn him about the newly created user
- begin
- if !LinkedData.settings.admin_emails.nil? && !LinkedData.settings.admin_emails.empty?
- LinkedData::Utils::Notifications.new_user(user)
- end
- rescue Exception => e
- end
+ user.save(send_notifications: false)
else
error 422, user.errors
end
diff --git a/helpers/access_control_helper.rb b/helpers/access_control_helper.rb
index 1de3bee5..74416866 100644
--- a/helpers/access_control_helper.rb
+++ b/helpers/access_control_helper.rb
@@ -10,11 +10,7 @@ module AccessControlHelper
def check_access(obj)
return obj unless LinkedData.settings.enable_security
if obj.is_a?(Enumerable)
- if obj.first.is_a?(LinkedData::Models::Base) && obj.first.access_based_on?
- check_access(obj.first)
- else
filter_access(obj)
- end
else
if obj.respond_to?(:read_restricted?) && obj.read_restricted?
readable = obj.readable?(env["REMOTE_USER"])
diff --git a/helpers/application_helper.rb b/helpers/application_helper.rb
index 5d6d1b0a..172170fa 100644
--- a/helpers/application_helper.rb
+++ b/helpers/application_helper.rb
@@ -31,6 +31,7 @@ def populate_from_params(obj, params)
# Deal with empty strings for String and URI
empty_string = value.is_a?(String) && value.empty?
old_string_value_exists = obj.respond_to?(attribute) && (obj.send(attribute).is_a?(String) || obj.send(attribute).is_a?(RDF::URI))
+ old_string_value_exists = old_string_value_exists || (obj.respond_to?(attribute) && obj.send(attribute).is_a?(LinkedData::Models::Base))
if old_string_value_exists && empty_string
value = nil
elsif empty_string
@@ -63,7 +64,7 @@ def populate_from_params(obj, params)
# Replace the initial value with the object, handling Arrays as appropriate
if value.is_a?(Array)
value = value.map {|e| attr_cls.find(uri_as_needed(e)).include(attr_cls.attributes).first}
- else
+ elsif !value.nil?
value = attr_cls.find(uri_as_needed(value)).include(attr_cls.attributes).first
end
elsif attr_cls
@@ -363,8 +364,6 @@ def retrieve_latest_submissions(options = {})
latest_submissions = page? ? submissions : {} # latest_submission doest not work with pagination
submissions.each do |sub|
- # To retrieve all metadata, but slow when a lot of ontologies
- sub.bring_remaining if includes_param.first == :all
unless page?
next if include_ready?(options) && !sub.ready?
next if sub.ontology.nil?
diff --git a/helpers/classes_helper.rb b/helpers/classes_helper.rb
index fa6c48cf..60becb22 100644
--- a/helpers/classes_helper.rb
+++ b/helpers/classes_helper.rb
@@ -32,23 +32,19 @@ def get_class(submission, load_attrs=nil)
load_children = load_attrs.delete :children
load_has_children = load_attrs.delete :hasChildren
- if !load_children
+ unless load_children
load_children = load_attrs.select { |x| x.instance_of?(Hash) && x.include?(:children) }
-
- if load_children.length == 0
- load_children = nil
- end
- if !load_children.nil?
- load_attrs = load_attrs.select { |x| !(x.instance_of?(Hash) && x.include?(:children)) }
- end
+ load_children = nil if load_children.length == 0
+ load_attrs = load_attrs.select { |x| !(x.instance_of?(Hash) && x.include?(:children)) } unless load_children.nil?
end
+
cls_uri = notation_to_class_uri(submission)
if cls_uri.nil?
cls_uri = RDF::URI.new(params[:cls])
- if !cls_uri.valid?
+ unless cls_uri.valid?
error 400, "The input class id '#{params[:cls]}' is not a valid IRI"
end
end
@@ -62,23 +58,38 @@ def get_class(submission, load_attrs=nil)
error 404,
"Resource '#{params[:cls]}' not found in ontology #{submission.ontology.acronym} submission #{submission.submissionId}"
end
- unless load_has_children.nil?
- cls.load_has_children
- end
- if !load_children.nil?
+
+ extra_include = []
+
+ extra_include << :hasChildren if load_has_children
+ extra_include << :isInActiveScheme if load_attrs.include?(:inScheme)
+ extra_include << :isInActiveCollection if load_attrs.include?(:memberOf)
+
+ cls.load_computed_attributes(to_load: extra_include ,
+ options: {schemes: concept_schemes, collections: concept_collections})
+
+
+ unless load_children.nil?
LinkedData::Models::Class.partially_load_children(
- [cls],500,cls.submission)
+ [cls], 500, cls.submission)
unless load_has_children.nil?
cls.children.each do |c|
c.load_has_children
end
end
end
- return cls
+ cls
end
end
+ def concept_schemes
+ params["concept_schemes"]&.split(',') || []
+ end
+
+ def concept_collections
+ params["concept_collections"]&.split(',') || []
+ end
end
end
diff --git a/helpers/request_params_helper.rb b/helpers/request_params_helper.rb
index 45091042..842ee0a7 100644
--- a/helpers/request_params_helper.rb
+++ b/helpers/request_params_helper.rb
@@ -42,7 +42,6 @@ def apply_submission_filters(query)
hasOntologyLanguage_acronym: params[:hasOntologyLanguage]&.split(',') , #%w[OWL SKOS],
ontology_hasDomain_acronym: params[:hasDomain]&.split(',') , #%w[Crop Vue_francais],
ontology_group_acronym: params[:group]&.split(','), #%w[RICE CROP],
- ontology_name: Array(params[:name]) + Array(params[:name]&.capitalize),
isOfType: params[:isOfType]&.split(','), #["http://omv.ontoware.org/2005/05/ontology#Vocabulary"],
hasFormalityLevel: params[:hasFormalityLevel]&.split(','), #["http://w3id.org/nkos/nkostype#thesaurus"],
ontology_viewingRestriction: params[:viewingRestriction]&.split(','), #["private"]
diff --git a/helpers/search_helper.rb b/helpers/search_helper.rb
index 10de14c0..071000d9 100644
--- a/helpers/search_helper.rb
+++ b/helpers/search_helper.rb
@@ -82,6 +82,9 @@ 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"
@@ -98,15 +101,15 @@ def get_term_search_query(text, params={})
if params[EXACT_MATCH_PARAM] == "true"
query = "\"#{solr_escape(text)}\""
- params["qf"] = "resource_id^20 prefLabelExact^10 synonymExact #{QUERYLESS_FIELDS_STR}"
- params["hl.fl"] = "resource_id prefLabelExact synonymExact #{QUERYLESS_FIELDS_STR}"
+ params["qf"] = "resource_id^20 prefLabelExact#{lang_suffix }^10 synonymExact#{lang_suffix } #{QUERYLESS_FIELDS_STR}"
+ params["hl.fl"] = "resource_id prefLabelExact#{lang_suffix } synonymExact#{lang_suffix } #{QUERYLESS_FIELDS_STR}"
elsif params[SUGGEST_PARAM] == "true" || text[-1] == '*'
text.gsub!(/\*+$/, '')
query = "\"#{solr_escape(text)}\""
params["qt"] = "/suggest_ncbo"
- params["qf"] = "prefLabelExact^100 prefLabelSuggestEdge^50 synonymSuggestEdge^10 prefLabelSuggestNgram synonymSuggestNgram resource_id #{QUERYLESS_FIELDS_STR}"
+ params["qf"] = "prefLabelExact#{lang_suffix }^100 prefLabelSuggestEdge^50 synonymSuggestEdge^10 prefLabelSuggestNgram synonymSuggestNgram resource_id #{QUERYLESS_FIELDS_STR}"
params["pf"] = "prefLabelSuggest^50"
- params["hl.fl"] = "prefLabelExact prefLabelSuggestEdge synonymSuggestEdge prefLabelSuggestNgram synonymSuggestNgram resource_id #{QUERYLESS_FIELDS_STR}"
+ params["hl.fl"] = "prefLabelExact#{lang_suffix } prefLabelSuggestEdge synonymSuggestEdge prefLabelSuggestNgram synonymSuggestNgram resource_id #{QUERYLESS_FIELDS_STR}"
else
if text.strip.empty?
query = '*'
@@ -114,9 +117,9 @@ def get_term_search_query(text, params={})
query = solr_escape(text)
end
- params["qf"] = "resource_id^100 prefLabelExact^90 prefLabel^70 synonymExact^50 synonym^10 #{QUERYLESS_FIELDS_STR}"
+ params["qf"] = "resource_id^100 prefLabelExact#{lang_suffix }^90 prefLabel#{lang_suffix }^70 synonymExact#{lang_suffix }^50 synonym#{lang_suffix }^10 #{QUERYLESS_FIELDS_STR}"
params["qf"] << " property" if params[INCLUDE_PROPERTIES_PARAM] == "true"
- params["hl.fl"] = "resource_id prefLabelExact prefLabel synonymExact synonym #{QUERYLESS_FIELDS_STR}"
+ params["hl.fl"] = "resource_id prefLabelExact#{lang_suffix } prefLabel#{lang_suffix } synonymExact#{lang_suffix } synonym#{lang_suffix } #{QUERYLESS_FIELDS_STR}"
params["hl.fl"] = "#{params["hl.fl"]} property" if params[INCLUDE_PROPERTIES_PARAM] == "true"
end
@@ -345,6 +348,7 @@ 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)
+ instance.prefLabel = instance.prefLabel.first if instance.prefLabel.is_a?(Array)
classes_hash[ont_uri_class_uri] = instance
end
diff --git a/helpers/submission_helper.rb b/helpers/submission_helper.rb
index c1ee5dd3..07f82138 100644
--- a/helpers/submission_helper.rb
+++ b/helpers/submission_helper.rb
@@ -3,6 +3,18 @@
module Sinatra
module Helpers
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]}
+ end
+
+ if includes.find{|v| v.is_a?(Hash) && v.keys.include?(:contact)}
+ includes << {:contact=>[:name, :email]}
+ end
+ includes
+ end
def submission_attributes_all
out = [LinkedData::Models::OntologySubmission.embed_values_hash]
@@ -16,14 +28,17 @@ def submission_attributes_all
def retrieve_submissions(options)
status = (options[:status] || "RDF").to_s.upcase
status = "RDF" if status.eql?("READY")
+ ontology_acronym = options[:ontology]
any = status.eql?("ANY")
include_views = options[:also_include_views] || false
includes, page, size, order_by, _ = settings_params(LinkedData::Models::OntologySubmission)
includes << :submissionStatus unless includes.include?(:submissionStatus)
submissions_query = LinkedData::Models::OntologySubmission
+ submissions_query = submissions_query.where(ontology: [acronym: ontology_acronym]) if ontology_acronym
+
if any
- submissions_query = submissions_query.where
+ submissions_query = submissions_query.where unless ontology_acronym
else
submissions_query = submissions_query.where({ submissionStatus: [code: status] })
end
@@ -32,24 +47,8 @@ def retrieve_submissions(options)
submissions_query = submissions_query.filter(Goo::Filter.new(ontology: [:viewOf]).unbound) unless include_views
submissions_query = submissions_query.filter(filter) if filter?
- # When asking to display all metadata, we are using bring_remaining on each submission. Slower but best way to retrieve all attrs
- if includes_param.first == :all
- includes = [:submissionId, { :contact => [:name, :email],
- :ontology => [:administeredBy, :acronym, :name, :summaryOnly, :ontologyType, :viewingRestriction, :acl,
- :group, :hasDomain, :views, :viewOf, :flat, :notes, :reviews, :projects],
- :submissionStatus => [:code], :hasOntologyLanguage => [:acronym], :metrics => [:classes, :individuals, :properties] },
- :submissionStatus]
- else
- 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] }
- end
- end
- submissions = submissions_query.include(includes)
+ submissions = submissions_query.include(submission_include_params)
if page?
submissions.page(page, size).all
else
diff --git a/helpers/users_helper.rb b/helpers/users_helper.rb
index 5d4266c1..e2c69e60 100644
--- a/helpers/users_helper.rb
+++ b/helpers/users_helper.rb
@@ -17,6 +17,55 @@ def filter_for_user_onts(obj)
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
+
+ return user if user.valid?
+
+ 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)).first
+
+ error 404, "User not found" unless user
+
+ user.show_apikey = true
+
+ [user, token.eql?(user.resetToken)]
+ 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/lib/rack/request_lang.rb b/lib/rack/request_lang.rb
new file mode 100644
index 00000000..b2221041
--- /dev/null
+++ b/lib/rack/request_lang.rb
@@ -0,0 +1,16 @@
+module Rack
+ class RequestLang
+
+ def initialize(app = nil, options = {})
+ @app = app
+ end
+
+ def call(env)
+ r = Rack::Request.new(env)
+ lang = r.params["lang"] || r.params["language"]
+ lang = lang.upcase.to_sym if lang
+ RequestStore.store[:requested_lang] = lang
+ @app.call(env)
+ end
+ end
+end
\ No newline at end of file
diff --git a/test/controllers/test_annotator_controller.rb b/test/controllers/test_annotator_controller.rb
index 0657ab91..47f45f40 100644
--- a/test/controllers/test_annotator_controller.rb
+++ b/test/controllers/test_annotator_controller.rb
@@ -262,14 +262,14 @@ def test_default_properties_output
assert_equal 9, annotations.length
annotations.sort! { |a,b| a["annotatedClass"]["prefLabel"].first.downcase <=> b["annotatedClass"]["prefLabel"].first.downcase }
assert_equal "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Aggregate_Human_Data", annotations.first["annotatedClass"]["@id"]
- assert_equal "Aggregate Human Data", annotations.first["annotatedClass"]["prefLabel"].first
+ assert_equal "Aggregate Human Data", Array(annotations.first["annotatedClass"]["prefLabel"]).first
params = {text: text, include: "prefLabel,definition"}
get "/annotator", params
assert last_response.ok?
annotations = MultiJson.load(last_response.body)
assert_equal 9, annotations.length
- annotations.sort! { |a,b| a["annotatedClass"]["prefLabel"].first.downcase <=> b["annotatedClass"]["prefLabel"].first.downcase }
+ annotations.sort! { |a,b| Array(a["annotatedClass"]["prefLabel"]).first.downcase <=> Array(b["annotatedClass"]["prefLabel"]).first.downcase }
assert_equal "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Aggregate_Human_Data", annotations.first["annotatedClass"]["@id"]
assert_equal ["A resource that provides data from clinical care that comprises combined data from multiple individual human subjects."], annotations.first["annotatedClass"]["definition"]
end
diff --git a/test/controllers/test_ontologies_controller.rb b/test/controllers/test_ontologies_controller.rb
index dc79359b..34f8c4dc 100644
--- a/test/controllers/test_ontologies_controller.rb
+++ b/test/controllers/test_ontologies_controller.rb
@@ -254,6 +254,32 @@ def test_download_acl_only
end
+ def test_detach_a_view
+ view = Ontology.find(@@view_acronym).include(:viewOf).first
+ ont = view.viewOf
+ refute_nil view
+ refute_nil ont
+
+ remove_view_of = {viewOf: ''}
+ patch "/ontologies/#{@@view_acronym}", MultiJson.dump(remove_view_of), "CONTENT_TYPE" => "application/json"
+
+ assert last_response.status == 204
+
+ get "/ontologies/#{@@view_acronym}"
+ onto = MultiJson.load(last_response.body)
+ assert_nil onto["viewOf"]
+
+
+ add_view_of = {viewOf: @@acronym}
+ patch "/ontologies/#{@@view_acronym}", MultiJson.dump(add_view_of), "CONTENT_TYPE" => "application/json"
+
+ assert last_response.status == 204
+
+ get "/ontologies/#{@@view_acronym}"
+ onto = MultiJson.load(last_response.body)
+ assert_equal onto["viewOf"], ont.id.to_s
+ end
+
private
def check400(response)
diff --git a/test/controllers/test_ontology_submissions_controller.rb b/test/controllers/test_ontology_submissions_controller.rb
index 9ee81257..77b6e6bc 100644
--- a/test/controllers/test_ontology_submissions_controller.rb
+++ b/test/controllers/test_ontology_submissions_controller.rb
@@ -39,6 +39,12 @@ def self._create_onts
ont.save
end
+ def setup
+ delete_ontologies_and_submissions
+ ont = Ontology.new(acronym: @@acronym, name: @@name, administeredBy: [@@user])
+ ont.save
+ end
+
def test_submissions_for_given_ontology
num_onts_created, created_ont_acronyms = create_ontologies_and_submissions(ont_count: 1)
ontology = created_ont_acronyms.first
@@ -210,4 +216,114 @@ def test_submissions_pagination
submissions = MultiJson.load(last_response.body)
assert_equal 1, submissions["collection"].length
end
+
+
+ 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: [])
+
+ 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?
+ submissions = MultiJson.load(last_response.body)
+
+ assert_equal ontology_count, submissions.size
+ assert(submissions.all? { |sub| submission_default_attributes.eql?(submission_keys(sub)) })
+
+ 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)) })
+ end
+
+ 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: [])
+ def submission_all_attributes
+ attrs = OntologySubmission.goo_attrs_to_load([:all])
+ embed_attrs = attrs.select { |x| x.is_a?(Hash) }.first
+
+ 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")
+
+ assert last_response.ok?
+ 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])) })
+
+ get("/ontologies/#{created_ont_acronyms.first}/submissions?include=all&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_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])) })
+
+ 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])))
+
+ 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])))
+ end
+
+ 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'
+
+ get("/submissions?include=#{include}&display_links=false&display_context=false")
+
+ 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])) })
+
+ 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])) })
+
+ 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])))
+
+ 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])))
+ 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
+
+ private
+ def submission_keys(sub)
+ sub.to_hash.keys - %w[@id @type id]
+ end
end
diff --git a/test/controllers/test_schemes_controller.rb b/test/controllers/test_schemes_controller.rb
index ebabc42f..d4504aa3 100644
--- a/test/controllers/test_schemes_controller.rb
+++ b/test/controllers/test_schemes_controller.rb
@@ -61,4 +61,21 @@ def test_calls_not_found
assert_equal 404, last_response.status
end
+
+ def test_class_tree
+ ont = Ontology.find('INRAETHES-0').include(:acronym).first
+ sub = ont.latest_submission
+ sub.bring_remaining
+ sub.uri = RDF::URI.new('http://opendata.inrae.fr/thesaurusINRAE/domainesINRAE')
+ sub.hasOntologyLanguage = LinkedData::Models::OntologyFormat.find('SKOS').first
+ sub.save
+
+ cls = 'http://opendata.inrae.fr/thesaurusINRAE/d_6'
+ get "ontologies/INRAETHES-0/classes/#{CGI.escape(cls)}/tree"
+
+ classes = MultiJson.load(last_response.body)
+
+ refute_nil classes.select{|x| x['@id'].eql?(cls)}.first['isInActiveScheme']
+ refute_nil classes.select{|x| x['@id'].eql?(cls)}.first['isInActiveCollection']
+ end
end
diff --git a/test/controllers/test_search_controller.rb b/test/controllers/test_search_controller.rb
index 21a3dd18..74be75d2 100644
--- a/test/controllers/test_search_controller.rb
+++ b/test/controllers/test_search_controller.rb
@@ -213,4 +213,48 @@ def test_search_provisional_class
assert_equal @@test_pc_child.label, provisional[0]["prefLabel"].first
end
+ def test_multilingual_search
+ get "/search?q=Activity&ontologies=BROSEARCHTEST-0"
+ res = MultiJson.load(last_response.body)
+ refute_equal 0, res["totalCount"]
+
+ doc = res["collection"].select{|doc| doc["@id"].to_s.eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+ refute_nil doc
+
+ #res = LinkedData::Models::Class.search("prefLabel_none:Activity", {:fq => "submissionAcronym:BROSEARCHTEST-0", :start => 0, :rows => 80}, :main)
+ #refute_equal 0, res["response"]["numFound"]
+ #refute_nil res["response"]["docs"].select{|doc| doc["resource_id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+ get "/search?q=Activit%C3%A9&ontologies=BROSEARCHTEST-0&lang=fr"
+ res = MultiJson.load(last_response.body)
+ refute_equal 0, res["totalCount"]
+ refute_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+
+
+ get "/search?q=ActivityEnglish&ontologies=BROSEARCHTEST-0&lang=en"
+ res = MultiJson.load(last_response.body)
+ refute_equal 0, res["totalCount"]
+ refute_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+
+ get "/search?q=ActivityEnglish&ontologies=BROSEARCHTEST-0&lang=fr&require_exact_match=true"
+ res = MultiJson.load(last_response.body)
+ assert_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+ get "/search?q=ActivityEnglish&ontologies=BROSEARCHTEST-0&lang=en&require_exact_match=true"
+ res = MultiJson.load(last_response.body)
+ refute_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+ get "/search?q=Activity&ontologies=BROSEARCHTEST-0&lang=en&require_exact_match=true"
+ res = MultiJson.load(last_response.body)
+ assert_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+ get "/search?q=Activit%C3%A9&ontologies=BROSEARCHTEST-0&lang=fr&require_exact_match=true"
+ res = MultiJson.load(last_response.body)
+ refute_nil res["collection"].select{|doc| doc["@id"].eql?('http://bioontology.org/ontologies/Activity.owl#Activity')}.first
+
+
+ end
+
end
diff --git a/test/controllers/test_users_controller.rb b/test/controllers/test_users_controller.rb
index 337da52e..3710b503 100644
--- a/test/controllers/test_users_controller.rb
+++ b/test/controllers/test_users_controller.rb
@@ -100,4 +100,40 @@ def test_authentication
assert user["username"].eql?(@@usernames.first)
end
+ 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
end
diff --git a/test/test_case.rb b/test/test_case.rb
index 7d3d0716..be162d5e 100644
--- a/test/test_case.rb
+++ b/test/test_case.rb
@@ -21,7 +21,9 @@
require_relative 'test_log_file'
require_relative '../app'
require 'minitest/unit'
+require 'webmock/minitest'
MiniTest::Unit.autorun
+WebMock.allow_net_connect!
require 'rack/test'
require 'multi_json'
require 'oj'