iqvoc 4.0.8 → 4.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +35 -18
- data/README.md +3 -2
- data/app/assets/stylesheets/iqvoc/components.css.scss +0 -6
- data/app/controllers/collections_controller.rb +30 -17
- data/app/controllers/concepts/alphabetical_controller.rb +15 -9
- data/app/{models/collection/member/concept.rb → controllers/concepts/expired_controller.rb} +13 -15
- data/app/controllers/concepts/hierarchical_controller.rb +3 -0
- data/app/controllers/concepts_controller.rb +2 -3
- data/app/controllers/instance_configuration_controller.rb +5 -6
- data/app/controllers/search_results_controller.rb +1 -2
- data/app/helpers/application_helper.rb +1 -5
- data/app/helpers/concepts_helper.rb +1 -1
- data/app/helpers/rdf_helper.rb +1 -1
- data/app/helpers/widget_helper.rb +3 -3
- data/app/models/collection/base.rb +64 -46
- data/app/models/collection/member/base.rb +12 -0
- data/app/models/collection/member/skos/base.rb +13 -12
- data/app/models/collection/skos/base.rb +1 -1
- data/app/models/collection/{member/collection.rb → skos/unordered.rb} +1 -16
- data/app/models/collection/unordered.rb +7 -0
- data/app/models/concept/base.rb +26 -107
- data/app/models/concept/relation/base.rb +4 -0
- data/app/models/concept/relation/skos/base.rb +17 -7
- data/app/models/concept/skos/base.rb +10 -1
- data/app/models/concept/skos/scheme.rb +1 -1
- data/app/models/concept/validations.rb +117 -0
- data/app/models/label/base.rb +4 -3
- data/app/models/labeling/skos/base.rb +24 -13
- data/app/models/match/skos/base.rb +24 -5
- data/app/models/note/skos/base.rb +17 -14
- data/app/views/collections/_form.html.erb +2 -2
- data/app/views/collections/_header.html.erb +2 -2
- data/app/views/collections/_sidebar.html.erb +3 -3
- data/app/views/collections/index.html.erb +1 -1
- data/app/views/collections/show.html.erb +1 -1
- data/app/views/collections/show.iqrdf +1 -1
- data/app/views/concepts/alphabetical/index.html.erb +1 -1
- data/app/views/concepts/expired/index.html.erb +16 -0
- data/app/views/concepts/notifications/_referenced_concepts.html.erb +1 -1
- data/app/views/concepts/sidebars/_plural.html.erb +4 -0
- data/app/views/dashboard/index.html.erb +1 -1
- data/app/views/layouts/_controls.html.erb +25 -24
- data/app/views/layouts/_navigation.html.erb +1 -1
- data/app/views/layouts/application.html.erb +0 -6
- data/app/views/partials/concept/_edit_link_base.html.erb +2 -1
- data/app/views/partials/labeling/skos/_base.html.erb +1 -2
- data/app/views/partials/note/_edit_base.html.erb +1 -1
- data/app/views/partials/note/skos/_edit_change_note.html.erb +1 -1
- data/app/views/rdf/scheme.iqrdf +1 -1
- data/app/views/search_results/_header.html.erb +2 -2
- data/app/views/search_results/_sidebar.html.erb +2 -2
- data/app/views/search_results/index.html.erb +1 -1
- data/app/views/triplestore_sync/index.html.erb +2 -2
- data/config/locales/de.yml +9 -2
- data/config/locales/en.yml +11 -4
- data/config/locales/pt.yml +8 -3
- data/config/routes.rb +15 -6
- data/db/migrate/20130227145825_fix_collection_type.rb +10 -0
- data/db/schema.rb +1 -1
- data/lib/generators/app/template.rb +20 -0
- data/lib/iqvoc/configuration/collection.rb +5 -5
- data/lib/iqvoc/configuration/concept.rb +7 -7
- data/lib/iqvoc/configuration/core.rb +11 -10
- data/lib/iqvoc/controller_extensions.rb +2 -5
- data/lib/iqvoc/inline_data_helper.rb +25 -3
- data/lib/iqvoc/instance_configuration.rb +1 -1
- data/lib/iqvoc/rdfapi.rb +56 -0
- data/lib/iqvoc/skos_importer.rb +88 -40
- data/lib/iqvoc/version.rb +1 -1
- data/lib/multi_logger.rb +38 -0
- data/lib/tasks/importer.rake +6 -1
- data/test/integration/browse_concepts_and_labels_test.rb +16 -0
- data/test/integration/instance_configuration_test.rb +5 -5
- data/test/integration/search_test.rb +18 -17
- data/test/unit/concept_test.rb +53 -4
- data/test/unit/inline_data_test.rb +61 -0
- data/test/unit/origin_test.rb +1 -1
- data/test/unit/rdfapi_test.rb +83 -0
- data/test/unit/skos_import_test.rb +1 -1
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_217bc0_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_2e83ff_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_469bdd_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_6da8d5_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_cd0a0a_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_d8e7f3_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_f9bd01_256x240.png +0 -0
- data/vendor/assets/stylesheets/{jquery-ui-1.8.23.custom.css → jquery-ui-1.8.23.custom.css.scss} +17 -17
- metadata +29 -131
- data/app/controllers/collections/hierarchical_controller.rb +0 -44
- data/public/assets/ajax-loader-dada1fbb71d7fb80d8dde7a031ae6cd0.gif +0 -0
- data/public/assets/ajax-loader.gif +0 -0
- data/public/assets/arrow_down-07c5dea12928d65fcc31c08279366170.gif +0 -0
- data/public/assets/arrow_down.gif +0 -0
- data/public/assets/arrow_up-51ede92c113b9a870e7a306907360ba8.gif +0 -0
- data/public/assets/arrow_up.gif +0 -0
- data/public/assets/bootstrap/bootstrap-2012a68e8267282c0a2c177d7005ae6d.css +0 -9
- data/public/assets/bootstrap/bootstrap-2012a68e8267282c0a2c177d7005ae6d.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap-35fd77cdf54a8cb63a39d8d0cea7a746.js +0 -19
- data/public/assets/bootstrap/bootstrap-35fd77cdf54a8cb63a39d8d0cea7a746.js.gz +0 -0
- data/public/assets/bootstrap/bootstrap-responsive-609b376f4bb032588c054b563d4bca1f.css +0 -9
- data/public/assets/bootstrap/bootstrap-responsive-609b376f4bb032588c054b563d4bca1f.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap-responsive.css +0 -9
- data/public/assets/bootstrap/bootstrap-responsive.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap.css +0 -9
- data/public/assets/bootstrap/bootstrap.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap.js +0 -19
- data/public/assets/bootstrap/bootstrap.js.gz +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-0e7ff93d8f48fe1f5f762e4312e78da7.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-white-ef3d5b8d6a297804352b4a46fdb5466d.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-white.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings.png +0 -0
- data/public/assets/file-58ce0b58f19dfe871b25270e98cff66c.gif +0 -0
- data/public/assets/file.gif +0 -0
- data/public/assets/folder-5c5b1fd2f1ece710f9159f05cc2aaaa8.gif +0 -0
- data/public/assets/folder-closed-8b61fc55011d534f0216c1150994f229.gif +0 -0
- data/public/assets/folder-closed.gif +0 -0
- data/public/assets/folder.gif +0 -0
- data/public/assets/html5-05e1be9157c8366db72fb7a1bcc8daff.js +0 -3
- data/public/assets/html5-05e1be9157c8366db72fb7a1bcc8daff.js.gz +0 -0
- data/public/assets/html5.js +0 -3
- data/public/assets/html5.js.gz +0 -0
- data/public/assets/iqvoc/ie_fixes-6a106c21d979ccdd1f6bf1cb129a0e69.css +0 -1
- data/public/assets/iqvoc/ie_fixes-6a106c21d979ccdd1f6bf1cb129a0e69.css.gz +0 -0
- data/public/assets/iqvoc/ie_fixes.css +0 -1
- data/public/assets/iqvoc/ie_fixes.css.gz +0 -0
- data/public/assets/iqvoc_logo-316859a511c646918fe75e92fa0bf6ac.png +0 -0
- data/public/assets/iqvoc_logo.png +0 -0
- data/public/assets/jquery-ui/ui-bg_flat_0_aaaaaa_40x100-a1eb3e0764573ed4b261ca742ed96ac3.png +0 -0
- data/public/assets/jquery-ui/ui-bg_flat_55_fbec88_40x100-439ee8e6c8ce855f43ed4d7b90684720.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_75_d0e5f5_1x400-9357836db77954d0d8c5feb259635223.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_85_dfeffc_1x400-7beb11d1590fb2fb1ef5c754100a078a.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_95_fef1ec_1x400-c723e9a2b50006c6054836a10b76bb84.png +0 -0
- data/public/assets/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100-cb26f48ac4912c23ce301c69c474d306.png +0 -0
- data/public/assets/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100-519299e2aa31bffdd4fed34b4fac603d.png +0 -0
- data/public/assets/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100-27e08524d3d56bb59e354435b663c3ac.png +0 -0
- data/public/assets/jquery-ui/ui-icons_217bc0_256x240-ed26778199d8722ae064038a1e841bc8.png +0 -0
- data/public/assets/jquery-ui/ui-icons_2e83ff_256x240-94086d0ce953eb0887ab1b8140903af9.png +0 -0
- data/public/assets/jquery-ui/ui-icons_469bdd_256x240-1c055f2d65517ef8faf1d1999c8ac2fa.png +0 -0
- data/public/assets/jquery-ui/ui-icons_6da8d5_256x240-8f5b417c5604f1b7b5965c98754c33b9.png +0 -0
- data/public/assets/jquery-ui/ui-icons_cd0a0a_256x240-8b44e266bdc1f57f1393579591f89222.png +0 -0
- data/public/assets/jquery-ui/ui-icons_d8e7f3_256x240-1b415e411069df902e6f417cc014172c.png +0 -0
- data/public/assets/jquery-ui/ui-icons_f9bd01_256x240-4553d0576c0498ca4c776aa77aa80833.png +0 -0
- data/public/assets/json2-b08b7b9af3e715f42c088ac728f62a2b.js +0 -157
- data/public/assets/json2-b08b7b9af3e715f42c088ac728f62a2b.js.gz +0 -0
- data/public/assets/json2.js +0 -157
- data/public/assets/json2.js.gz +0 -0
- data/public/assets/manifest-3ce8edde69d5d291841ef7c49daaa9cb.js +0 -21
- data/public/assets/manifest-3ce8edde69d5d291841ef7c49daaa9cb.js.gz +0 -0
- data/public/assets/manifest-c0eca563fd9f16907d302af9a2dcae6b.css +0 -51
- data/public/assets/manifest-c0eca563fd9f16907d302af9a2dcae6b.css.gz +0 -0
- data/public/assets/manifest.css +0 -51
- data/public/assets/manifest.css.gz +0 -0
- data/public/assets/manifest.js +0 -21
- data/public/assets/manifest.js.gz +0 -0
- data/public/assets/manifest.yml +0 -47
- data/public/assets/minus-1d0fae0720bab52bd98598218e8345c0.gif +0 -0
- data/public/assets/minus.gif +0 -0
- data/public/assets/plus-1a29e46532f839ed9c977ef4613d079f.gif +0 -0
- data/public/assets/plus.gif +0 -0
- data/public/assets/spinner_16x16-17dcf941457ae4e702f4600e714b21c1.gif +0 -0
- data/public/assets/spinner_16x16.gif +0 -0
- data/public/assets/spinner_24x24-78c707c1921b93962ea5edd7f4a74134.gif +0 -0
- data/public/assets/spinner_24x24.gif +0 -0
- data/public/assets/treeview-black-c46d96020e5d79c652af0fb0c6656384.gif +0 -0
- data/public/assets/treeview-black-line-0903c58efd34c3203d132e6f873049f6.gif +0 -0
- data/public/assets/treeview-black-line.gif +0 -0
- data/public/assets/treeview-black.gif +0 -0
- data/public/assets/treeview-default-ee6298d311205d21dc57c01c0696df70.gif +0 -0
- data/public/assets/treeview-default-line-2c4106cfd4d322c6e6565f80702c27cb.gif +0 -0
- data/public/assets/treeview-default-line.gif +0 -0
- data/public/assets/treeview-default.gif +0 -0
- data/public/assets/treeview-famfamfam-20dfef13cd5fd1e08fb61ee68eb9d3fa.gif +0 -0
- data/public/assets/treeview-famfamfam-line-a02cce2b80977e066df83137aae71fa8.gif +0 -0
- data/public/assets/treeview-famfamfam-line.gif +0 -0
- data/public/assets/treeview-famfamfam.gif +0 -0
- data/public/assets/treeview-gray-01bfdcd116e081e23daf13024fd3e4e0.gif +0 -0
- data/public/assets/treeview-gray-line-029b3a7b92ed10ea6c4b6289cb9fa0e3.gif +0 -0
- data/public/assets/treeview-gray-line.gif +0 -0
- data/public/assets/treeview-gray.gif +0 -0
- data/public/assets/treeview-red-2a5abbce598d05c864d845998381eef6.gif +0 -0
- data/public/assets/treeview-red-line-f51e6c30aa3b0ff856900ba85d769f1c.gif +0 -0
- data/public/assets/treeview-red-line.gif +0 -0
- data/public/assets/treeview-red.gif +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_217bc0_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_469bdd_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_6da8d5_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_d8e7f3_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_f9bd01_256x240.png +0 -0
- data/vendor/assets/javascripts/json2.js +0 -487
@@ -9,13 +9,13 @@ module Iqvoc
|
|
9
9
|
Iqvoc.first_level_class_configuration_modules << self
|
10
10
|
|
11
11
|
mattr_accessor :base_class_name, :root_class_name,
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
:broader_relation_class_name, :further_relation_class_names,
|
13
|
+
:pref_labeling_class_name,
|
14
|
+
:match_class_names,
|
15
|
+
:note_class_names,
|
16
|
+
:additional_association_class_names,
|
17
|
+
:view_sections,
|
18
|
+
:include_module_names
|
19
19
|
|
20
20
|
self.base_class_name = 'Concept::SKOS::Base'
|
21
21
|
self.root_class_name = 'Concept::SKOS::Scheme'
|
@@ -14,8 +14,11 @@ module Iqvoc
|
|
14
14
|
:first_level_class_configuration_modules,
|
15
15
|
:ability_class_name,
|
16
16
|
:navigation_items,
|
17
|
+
:localized_routes,
|
17
18
|
:core_assets
|
18
19
|
|
20
|
+
self.localized_routes = [] # routing extensibility hook
|
21
|
+
|
19
22
|
self.navigation_items = [
|
20
23
|
{
|
21
24
|
:content => proc { link_to "Dashboard", dashboard_path },
|
@@ -58,7 +61,6 @@ module Iqvoc
|
|
58
61
|
bootstrap/bootstrap.css
|
59
62
|
bootstrap/bootstrap-responsive.css
|
60
63
|
iqvoc/ie_fixes.css
|
61
|
-
json2.js
|
62
64
|
bootstrap/bootstrap.js
|
63
65
|
html5.js
|
64
66
|
)
|
@@ -90,9 +92,9 @@ module Iqvoc
|
|
90
92
|
# initialize
|
91
93
|
self.config.register_settings({
|
92
94
|
"title" => "iQvoc",
|
93
|
-
"available_languages" => ["en", "de"],
|
94
95
|
"languages.pref_labeling" => ["en", "de"],
|
95
|
-
"languages.further_labelings.Labeling::SKOS::AltLabel" => ["en", "de"]
|
96
|
+
"languages.further_labelings.Labeling::SKOS::AltLabel" => ["en", "de"],
|
97
|
+
"note_languages" => ["en", "de"]
|
96
98
|
})
|
97
99
|
self.config.initialize_cache
|
98
100
|
end
|
@@ -148,8 +150,12 @@ module Iqvoc
|
|
148
150
|
return config["title"]
|
149
151
|
end
|
150
152
|
|
151
|
-
def
|
152
|
-
return config["
|
153
|
+
def note_languages
|
154
|
+
return config["note_languages"]
|
155
|
+
end
|
156
|
+
|
157
|
+
def all_languages
|
158
|
+
(Iqvoc::Concept.pref_labeling_languages + Iqvoc::Concept.further_labeling_class_names.values.flatten + note_languages).compact.map(&:to_s).uniq
|
153
159
|
end
|
154
160
|
|
155
161
|
# @deprecated
|
@@ -158,11 +164,6 @@ module Iqvoc
|
|
158
164
|
self.config.register_setting("title", value)
|
159
165
|
end
|
160
166
|
|
161
|
-
# @deprecated
|
162
|
-
def available_languages=(value)
|
163
|
-
ActiveSupport::Deprecation.warn "available_languages has been moved into instance configuration", caller
|
164
|
-
self.config.register_setting("available_languages", value)
|
165
|
-
end
|
166
167
|
end
|
167
168
|
|
168
169
|
end
|
@@ -19,7 +19,6 @@ module Iqvoc
|
|
19
19
|
|
20
20
|
def default_url_options(options = nil)
|
21
21
|
{ :format => params[:format], :lang => I18n.locale }.
|
22
|
-
reject { |key, value| key == :lang and value.to_s.strip.blank? }. # Strip out the lang parameter if it's empty.
|
23
22
|
merge(options || {})
|
24
23
|
end
|
25
24
|
|
@@ -53,9 +52,7 @@ module Iqvoc
|
|
53
52
|
end
|
54
53
|
|
55
54
|
def set_locale
|
56
|
-
if Iqvoc::Concept.pref_labeling_languages.include?(
|
57
|
-
I18n.locale = " "
|
58
|
-
elsif params[:lang] && Iqvoc::Concept.pref_labeling_languages.include?(params[:lang])
|
55
|
+
if params[:lang].present? && Iqvoc::Concept.pref_labeling_languages.include?(params[:lang])
|
59
56
|
I18n.locale = params[:lang]
|
60
57
|
else
|
61
58
|
I18n.locale = Iqvoc::Concept.pref_labeling_languages.first
|
@@ -65,7 +62,7 @@ module Iqvoc
|
|
65
62
|
def concept_widget_data(concept, rank = nil)
|
66
63
|
data = {
|
67
64
|
:id => concept.origin,
|
68
|
-
:name => concept.pref_label.value.
|
65
|
+
:name => (concept.pref_label && concept.pref_label.value.presence || ":#{concept.origin}") + (concept.additional_info ? " (#{concept.additional_info })" : "")
|
69
66
|
}
|
70
67
|
data[:rank] = rank if rank
|
71
68
|
data
|
@@ -14,12 +14,34 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require 'csv'
|
18
|
+
|
17
19
|
module Iqvoc
|
18
20
|
module InlineDataHelper
|
19
21
|
|
20
|
-
# delimiters for strings representing a list of values
|
21
|
-
|
22
|
-
|
22
|
+
# delimiters for strings representing a list of values - XXX: lacks encapsulation
|
23
|
+
JOINER = ", "
|
24
|
+
SPLITTER = /[,\n] */
|
25
|
+
|
26
|
+
CSV_OPTIONS = {
|
27
|
+
:col_sep => ", ",
|
28
|
+
:quote_char => '"'
|
29
|
+
}
|
30
|
+
|
31
|
+
def self.parse_inline_values(inline_values)
|
32
|
+
options = CSV_OPTIONS.clone
|
33
|
+
options[:col_sep] = options[:col_sep].strip
|
34
|
+
begin
|
35
|
+
values = inline_values.parse_csv(options)
|
36
|
+
rescue CSV::MalformedCSVError => exc
|
37
|
+
values = inline_values.parse_csv(CSV_OPTIONS)
|
38
|
+
end
|
39
|
+
values ? values.map(&:strip) : []
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.generate_inline_values(values)
|
43
|
+
values.to_csv(CSV_OPTIONS).strip
|
44
|
+
end
|
23
45
|
|
24
46
|
end
|
25
47
|
end
|
@@ -69,7 +69,7 @@ module Iqvoc
|
|
69
69
|
|
70
70
|
# retrieve individual setting, using default value as fallback
|
71
71
|
def [](key)
|
72
|
-
initialize_cache
|
72
|
+
initialize_cache if @settings.blank?
|
73
73
|
return @settings[key]
|
74
74
|
end
|
75
75
|
|
data/lib/iqvoc/rdfapi.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2011 innoQ Deutschland GmbH
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
module Iqvoc
|
18
|
+
module RDFAPI
|
19
|
+
FIRST_LEVEL_OBJECT_CLASSES = [Iqvoc::Concept.base_class, Iqvoc::Collection.base_class]
|
20
|
+
SECOND_LEVEL_OBJECT_CLASSES = Iqvoc::Concept.labeling_classes.keys +
|
21
|
+
Iqvoc::Concept.note_classes +
|
22
|
+
Iqvoc::Concept.relation_classes +
|
23
|
+
Iqvoc::Concept.match_classes +
|
24
|
+
[Iqvoc::Collection.member_class]
|
25
|
+
|
26
|
+
OBJECT_DICTIONARY = FIRST_LEVEL_OBJECT_CLASSES.inject({}) do |hash, klass|
|
27
|
+
hash["#{klass.rdf_namespace}:#{klass.rdf_class}"] = klass
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
|
31
|
+
PREDICATE_DICTIONARY = SECOND_LEVEL_OBJECT_CLASSES.inject({}) do |hash, klass|
|
32
|
+
hash["#{klass.rdf_namespace}:#{klass.rdf_predicate}"] = klass
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.devour(rdf_subject, rdf_predicate, rdf_object)
|
37
|
+
case rdf_predicate
|
38
|
+
when 'a', 'rdf:type'
|
39
|
+
case rdf_object
|
40
|
+
when String
|
41
|
+
target = OBJECT_DICTIONARY[rdf_object] || rdf_object.constantize
|
42
|
+
else
|
43
|
+
target = rdf_object
|
44
|
+
end
|
45
|
+
target.find_or_initialize_by_origin(rdf_subject)
|
46
|
+
when String
|
47
|
+
# dictionary lookup
|
48
|
+
target = PREDICATE_DICTIONARY[rdf_predicate] || rdf_predicate.constantize
|
49
|
+
target.build_from_rdf(rdf_subject, target, rdf_object)
|
50
|
+
else # is a class
|
51
|
+
rdf_predicate.build_from_rdf(rdf_subject, rdf_predicate, rdf_object)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
data/lib/iqvoc/skos_importer.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
+
require 'iqvoc/rdfapi'
|
2
|
+
|
1
3
|
module Iqvoc
|
2
4
|
class SkosImporter
|
3
5
|
|
4
6
|
FIRST_LEVEL_OBJECT_CLASSES = [Iqvoc::Concept.base_class, Iqvoc::Collection.base_class]
|
5
7
|
SECOND_LEVEL_OBJECT_CLASSES = Iqvoc::Concept.labeling_classes.keys +
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
Iqvoc::Concept.note_classes +
|
9
|
+
Iqvoc::Concept.relation_classes +
|
10
|
+
Iqvoc::Concept.match_classes +
|
11
|
+
[Iqvoc::Collection.member_class]
|
10
12
|
|
11
13
|
def initialize(file, default_namespace_url, logger = Rails.logger)
|
12
|
-
|
13
14
|
@logger = logger
|
14
15
|
|
15
16
|
unless file.is_a?(File) || file.is_a?(Array)
|
@@ -28,69 +29,90 @@ module Iqvoc
|
|
28
29
|
@prefixes[uri] = "#{pref.to_s}:"
|
29
30
|
end
|
30
31
|
|
31
|
-
@seen_first_level_objects = {}
|
32
|
+
@seen_first_level_objects = {} # Concept cache (don't load any concept twice from db)
|
33
|
+
@new_subjects = [] # Concepts to be published later
|
34
|
+
|
35
|
+
# Triples the importer doesn't understand immediately. Example:
|
36
|
+
#
|
37
|
+
# :a skos:prefLabel "foo". # => What is :a? Remember this and try again later
|
38
|
+
# ....
|
39
|
+
# :a rdf:type skos:Concept # => Now I know :a, good I remebered it's prefLabel...
|
40
|
+
@unknown_second_level_tripes = []
|
41
|
+
|
42
|
+
# Hash of arrays of arrays: { "_:n123" => [["pred1", "obj1"], ["pred2", "obj2"]] }
|
32
43
|
@blank_nodes = {}
|
33
44
|
|
34
45
|
@existing_origins = {} # To prevent the creation of first level objects we already have
|
35
|
-
FIRST_LEVEL_OBJECT_CLASSES.each do |klass|
|
36
|
-
klass.select(
|
46
|
+
Iqvoc::RDFAPI::FIRST_LEVEL_OBJECT_CLASSES.each do |klass|
|
47
|
+
klass.select('origin').all.each do |thing|
|
37
48
|
@existing_origins[thing.origin] = klass
|
38
49
|
end
|
39
50
|
end
|
40
51
|
|
41
|
-
import
|
52
|
+
import file
|
42
53
|
end
|
43
54
|
|
44
55
|
private
|
45
56
|
|
46
57
|
def import(file)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
58
|
+
ActiveSupport.run_load_hooks(:skos_importer_before_import, self)
|
59
|
+
|
60
|
+
start = Time.now
|
51
61
|
|
52
|
-
|
53
|
-
types = {} # type identifier ("namespace:SomeClass") to Iqvoc class assignment hash
|
62
|
+
first_level_types = {} # type identifier ("namespace:SomeClass") to Iqvoc class assignment hash
|
54
63
|
FIRST_LEVEL_OBJECT_CLASSES.each do |klass|
|
55
|
-
|
64
|
+
first_level_types["#{klass.rdf_namespace}:#{klass.rdf_class}"] = klass
|
65
|
+
end
|
66
|
+
second_level_types = {}
|
67
|
+
SECOND_LEVEL_OBJECT_CLASSES.each do |klass|
|
68
|
+
second_level_types["#{klass.rdf_namespace}:#{klass.rdf_predicate}"] = klass
|
56
69
|
end
|
57
70
|
|
58
71
|
file.each do |line|
|
59
|
-
|
72
|
+
identify_blank_nodes(*extract_triple(line)) ||
|
73
|
+
import_first_level_objects(first_level_types, *extract_triple(line)) ||
|
74
|
+
import_second_level_objects(second_level_types, false, *extract_triple(line))
|
60
75
|
end
|
61
|
-
new_subjects = @seen_first_level_objects.dup # Remember the objects seen yet, because they are the ones to be published later
|
62
76
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
types["#{klass.rdf_namespace}:#{klass.rdf_predicate}"] = klass
|
67
|
-
end
|
68
|
-
file.each do |line|
|
69
|
-
import_second_level_objects(types, *extract_triple(line))
|
77
|
+
@logger.debug("Computing 'forward' defined triples...")
|
78
|
+
@unknown_second_level_tripes.each do |s, p, o|
|
79
|
+
import_second_level_objects(second_level_types, true, s, p, o)
|
70
80
|
end
|
71
81
|
|
72
|
-
|
82
|
+
first_import_step_done = Time.now
|
83
|
+
@logger.debug("Basic import done (took #{(first_import_step_done - start).to_i} seconds).")
|
84
|
+
|
85
|
+
@logger.debug("Publishing #{@new_subjects.count} new subjects...")
|
86
|
+
published = 0
|
87
|
+
@new_subjects.each do |subject|
|
73
88
|
if subject.valid_with_full_validation?
|
74
89
|
subject.publish
|
75
90
|
subject.save!
|
91
|
+
published += 1
|
76
92
|
else
|
77
|
-
@logger.warn "WARNING:
|
93
|
+
@logger.warn "WARNING: Publishing failed! Subject ('#{subject.origin}') invalid: #{subject.errors.to_hash.inspect}"
|
78
94
|
end
|
79
95
|
end
|
80
96
|
|
97
|
+
done = Time.now
|
98
|
+
@logger.debug("Publishing of #{published} subjects done (took #{(done - first_import_step_done).to_i} seconds). #{@new_subjects.count - published} where invalid.")
|
99
|
+
puts "Imported #{published} valid and #{@new_subjects.count - published} invalid subjects in #{(done - start).to_i} seconds."
|
100
|
+
puts " First step took #{(first_import_step_done - start).to_i} seconds, publishing took #{(done - first_import_step_done).to_i} seconds."
|
101
|
+
|
102
|
+
ActiveSupport.run_load_hooks(:skos_importer_after_import, self)
|
81
103
|
end
|
82
104
|
|
83
105
|
def identify_blank_nodes(subject, predicate, object)
|
84
106
|
if blank_node?(subject)
|
85
107
|
@blank_nodes[subject] ||= []
|
86
108
|
@blank_nodes[subject] << [predicate, object]
|
109
|
+
true
|
110
|
+
else
|
111
|
+
false
|
87
112
|
end
|
88
113
|
end
|
89
114
|
|
90
115
|
def import_first_level_objects(types, subject, predicate, object)
|
91
|
-
@logger.debug "types: #{types}"
|
92
|
-
@logger.debug "predicate: #{predicate}"
|
93
|
-
@logger.debug "subject: #{subject}"
|
94
116
|
if (predicate == "rdf:type" && types[object] && subject =~ /^:(.+)$/)
|
95
117
|
# We've found a subject definition with a class we know and which is in our responsibility (":")
|
96
118
|
origin = $1
|
@@ -103,20 +125,29 @@ module Iqvoc
|
|
103
125
|
end
|
104
126
|
else
|
105
127
|
@seen_first_level_objects[origin] = types[object].create!(:origin => origin)
|
128
|
+
@new_subjects << @seen_first_level_objects[origin]
|
106
129
|
end
|
130
|
+
true
|
131
|
+
else
|
132
|
+
false
|
107
133
|
end
|
108
|
-
|
109
134
|
end
|
110
135
|
|
111
|
-
def import_second_level_objects(types, subject, predicate, object)
|
136
|
+
def import_second_level_objects(types, final, subject, predicate, object)
|
112
137
|
return unless (subject =~ /^:(.*)$/ && types[predicate]) # We're not responsible for this
|
113
138
|
|
139
|
+
initial_triple = [subject, predicate, object]
|
140
|
+
|
114
141
|
# Load the subject and replace the string by the respective data object
|
115
142
|
subject_origin = $1
|
116
143
|
subject = load_first_level_object(subject_origin)
|
117
144
|
unless subject
|
118
|
-
|
119
|
-
|
145
|
+
if final
|
146
|
+
@logger.warn "Iqvoc::SkosImporter: Couldn't find Subject with origin '#{subject_origin}. Skipping entry '#{subject} #{predicate} #{object}.'"
|
147
|
+
else
|
148
|
+
@unknown_second_level_tripes << initial_triple
|
149
|
+
end
|
150
|
+
return false
|
120
151
|
end
|
121
152
|
|
122
153
|
# Load the data object for the object string if this is representing a thing in our domain
|
@@ -124,13 +155,28 @@ module Iqvoc
|
|
124
155
|
object_origin = $1
|
125
156
|
object = load_first_level_object(object_origin)
|
126
157
|
unless object
|
127
|
-
|
128
|
-
|
158
|
+
if final
|
159
|
+
@logger.warn "Iqvoc::SkosImporter: Couldn't find Object with origin '#{object_origin}. Skipping entry ':#{subject_origin} #{predicate} #{object}.'"
|
160
|
+
else
|
161
|
+
@unknown_second_level_tripes << initial_triple
|
162
|
+
end
|
163
|
+
return false
|
129
164
|
end
|
130
165
|
end
|
131
166
|
|
167
|
+
# If not in final mode every :my_concept :bla _:blank_node. triple should
|
168
|
+
# be saved for final mode. Why? Example:
|
169
|
+
#
|
170
|
+
# :a iqvoc:changeNote _:b01 # => I do not know know anything about the blank node now
|
171
|
+
# _:b01 dc:author "DHH"...
|
172
|
+
#
|
132
173
|
if blank_node?(object)
|
133
|
-
|
174
|
+
if final
|
175
|
+
object = @blank_nodes[object]
|
176
|
+
else
|
177
|
+
@unknown_second_level_tripes << initial_triple
|
178
|
+
return false
|
179
|
+
end
|
134
180
|
end
|
135
181
|
|
136
182
|
types[predicate].build_from_rdf(subject, predicate, object)
|
@@ -138,11 +184,12 @@ module Iqvoc
|
|
138
184
|
|
139
185
|
def load_first_level_object(origin)
|
140
186
|
unless @seen_first_level_objects[origin]
|
141
|
-
|
187
|
+
klass = @existing_origins[origin]
|
188
|
+
if klass
|
142
189
|
@seen_first_level_objects[origin] = klass.by_origin(origin).last
|
143
|
-
break if @seen_first_level_objects[origin]
|
144
190
|
end
|
145
191
|
end
|
192
|
+
|
146
193
|
@seen_first_level_objects[origin]
|
147
194
|
end
|
148
195
|
|
@@ -151,7 +198,7 @@ module Iqvoc
|
|
151
198
|
end
|
152
199
|
|
153
200
|
def extract_triple(line)
|
154
|
-
raise "'#{line}' doesn't look like valid ntriples data." unless line =~ /^(.*)\.\
|
201
|
+
raise "'#{line}' doesn't look like valid ntriples data." unless line =~ /^(.*)\.\s*$/
|
155
202
|
line = $1.squish
|
156
203
|
|
157
204
|
triple = line.split(' ', 3) # The first one are uris the last can be a literal too
|
@@ -171,5 +218,6 @@ module Iqvoc
|
|
171
218
|
triple
|
172
219
|
end
|
173
220
|
|
221
|
+
ActiveSupport.run_load_hooks(:skos_importer, self)
|
174
222
|
end
|
175
223
|
end
|
data/lib/iqvoc/version.rb
CHANGED
data/lib/multi_logger.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
class MultiLogger
|
2
|
+
|
3
|
+
attr_reader :loggers
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
@loggers = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def level=(level)
|
10
|
+
@loggers.each { |logger| logger.level = level }
|
11
|
+
end
|
12
|
+
|
13
|
+
def levels
|
14
|
+
@loggers.map(&:level)
|
15
|
+
end
|
16
|
+
|
17
|
+
def min_level
|
18
|
+
levels.min
|
19
|
+
end
|
20
|
+
|
21
|
+
def close
|
22
|
+
@loggers.map(&:close)
|
23
|
+
end
|
24
|
+
|
25
|
+
def add(level, *args)
|
26
|
+
@loggers.each { |logger| logger.add(level, *args) }
|
27
|
+
end
|
28
|
+
|
29
|
+
Logger::Severity.constants.each do |level|
|
30
|
+
define_method(level.downcase) do |*args|
|
31
|
+
@loggers.each { |logger| logger.send(level.downcase, *args) }
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method("#{ level.downcase }?".to_sym) do
|
35
|
+
min_level <= Logger::Severity.const_get(level)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/tasks/importer.rake
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'multi_logger'
|
2
|
+
|
1
3
|
namespace :iqvoc do
|
2
4
|
|
3
5
|
namespace :import do
|
@@ -8,7 +10,10 @@ namespace :iqvoc do
|
|
8
10
|
|
9
11
|
raise "You have to specify an url for the data file to be imported. Example: rake iqvoc:import:url URL=... NAMESPACE=" unless ENV['URL']
|
10
12
|
raise "You have to specify a default namespace for the data to be imported. Example: rake iqvoc:import:url URL=... NAMESPACE=" unless ENV['NAMESPACE']
|
11
|
-
|
13
|
+
|
14
|
+
stdout_logger = Logger.new(STDOUT)
|
15
|
+
stdout_logger.level = Logger::INFO
|
16
|
+
Iqvoc::SkosImporter.new(open(URI.parse(ENV['URL']).to_s), URI.parse(ENV['NAMESPACE']).to_s, MultiLogger.new(stdout_logger, Rails.logger))
|
12
17
|
end
|
13
18
|
|
14
19
|
end
|
@@ -58,4 +58,20 @@ class BrowseConceptsAndLabelsTest < ActionDispatch::IntegrationTest
|
|
58
58
|
"'#{@concepts[1].origin} a skos:Concept' missing in turtle view"
|
59
59
|
end
|
60
60
|
|
61
|
+
test "showing expired concepts" do
|
62
|
+
# prepare database with expired concept
|
63
|
+
concepts = [[:en, "Method"], [:de, "Methode"]].map do |lang, text|
|
64
|
+
FactoryGirl.create(:concept,
|
65
|
+
:expired_at => 2.days.ago,
|
66
|
+
:pref_labelings => [
|
67
|
+
FactoryGirl.create(:pref_labeling, :target => FactoryGirl.create(:pref_label, :language => lang, :value => text))
|
68
|
+
])
|
69
|
+
end
|
70
|
+
|
71
|
+
visit hierarchical_concepts_path(:lang => 'en')
|
72
|
+
click_link_or_button('Expired')
|
73
|
+
click_link_or_button('M')
|
74
|
+
assert page.has_content?(concepts.first.pref_label.to_s), 'should have one expired concept'
|
75
|
+
end
|
76
|
+
|
61
77
|
end
|
@@ -20,7 +20,7 @@ require 'integration_test_helper'
|
|
20
20
|
class InstanceConfigurationTest < ActionDispatch::IntegrationTest
|
21
21
|
|
22
22
|
test "configuration privileges" do
|
23
|
-
uri = "/config"
|
23
|
+
uri = "/en/config"
|
24
24
|
|
25
25
|
# guest
|
26
26
|
visit uri
|
@@ -37,7 +37,7 @@ class InstanceConfigurationTest < ActionDispatch::IntegrationTest
|
|
37
37
|
visit uri
|
38
38
|
assert_equal "/en/config.html", page.current_path
|
39
39
|
assert page.has_css?("input#config_title")
|
40
|
-
assert page.has_css?("input#
|
40
|
+
assert page.has_css?("input#config_note_languages")
|
41
41
|
assert page.has_selector?(:xpath, '//input[@id="config_languages.pref_labeling"]')
|
42
42
|
assert page.has_selector?(:xpath, '//input[@id="config_languages.further_labelings.Labeling::SKOS::AltLabel"]')
|
43
43
|
|
@@ -48,7 +48,7 @@ class InstanceConfigurationTest < ActionDispatch::IntegrationTest
|
|
48
48
|
assert page.find("a.brand").has_content? "iQvoc"
|
49
49
|
|
50
50
|
login "administrator"
|
51
|
-
visit "/config"
|
51
|
+
visit "/en/config"
|
52
52
|
|
53
53
|
fill_in "config_title", :with => "lorem ipsum"
|
54
54
|
click_button "Save"
|
@@ -62,9 +62,9 @@ class InstanceConfigurationTest < ActionDispatch::IntegrationTest
|
|
62
62
|
}
|
63
63
|
["reader", "editor", "publisher", "administrator"].each do |role|
|
64
64
|
login role
|
65
|
-
check_page.call "/config"
|
65
|
+
check_page.call "/en/config"
|
66
66
|
logout
|
67
|
-
check_page.call "/search"
|
67
|
+
check_page.call "/en/search"
|
68
68
|
end
|
69
69
|
|
70
70
|
# TODO: test routes-by-language availability, post-modification
|
@@ -31,7 +31,8 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# create collection
|
34
|
-
@collection = FactoryGirl.create(:collection,
|
34
|
+
@collection = FactoryGirl.create(:collection,
|
35
|
+
:members => @concepts.map { |c| Iqvoc::Collection.member_class.new(:target => c) },
|
35
36
|
:labelings => [], :pref_labelings => [
|
36
37
|
FactoryGirl.create(:pref_labeling,
|
37
38
|
:target => FactoryGirl.create(:pref_label, :language => :en, :value => "Alpha"))
|
@@ -49,9 +50,9 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
49
50
|
:type => 'Labels', :query => 'Forest', :query_type => 'contains',
|
50
51
|
:amount => 1, :result => 'Forest'
|
51
52
|
}].each { |q|
|
52
|
-
select q[:type]
|
53
|
+
find("#t").select q[:type]
|
53
54
|
fill_in "Search term(s)", :with => q[:query]
|
54
|
-
select q[:query_type]
|
55
|
+
find("#qt").select q[:query_type]
|
55
56
|
|
56
57
|
# select all languages
|
57
58
|
page.all(:css, ".lang_check").each do |cb|
|
@@ -72,8 +73,8 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
72
73
|
test "collection/concept filter" do
|
73
74
|
visit search_path(:lang => 'en', :format => 'html')
|
74
75
|
|
75
|
-
select "Labels"
|
76
|
-
select "contains"
|
76
|
+
find("#t").select "Labels"
|
77
|
+
find("#qt").select "contains"
|
77
78
|
fill_in "Search term(s)", :with => "Alpha"
|
78
79
|
click_button("Search")
|
79
80
|
assert page.has_css?("#search_results dt", :count => 1)
|
@@ -90,10 +91,10 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
90
91
|
test "searching within collections" do
|
91
92
|
visit search_path(:lang => 'en', :format => 'html')
|
92
93
|
|
93
|
-
select "Labels"
|
94
|
-
select "contains"
|
94
|
+
find("#t").select "Labels"
|
95
|
+
find("#qt").select "contains"
|
95
96
|
fill_in "Search term(s)", :with => "res"
|
96
|
-
select @collection.to_s
|
97
|
+
find("#c").select @collection.to_s
|
97
98
|
|
98
99
|
# select all languages
|
99
100
|
page.all(:css, ".lang_check").each do |cb|
|
@@ -128,10 +129,10 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
128
129
|
|
129
130
|
visit search_path(:lang => 'en', :format => 'html')
|
130
131
|
|
131
|
-
select "Notes"
|
132
|
-
select "contains"
|
132
|
+
find("#t").select "Notes"
|
133
|
+
find("#qt").select "contains"
|
133
134
|
fill_in "Search term(s)", :with => "ipsum"
|
134
|
-
select @collection.to_s
|
135
|
+
find("#c").select @collection.to_s
|
135
136
|
|
136
137
|
# select all languages
|
137
138
|
page.all(:css, ".lang_check").each do |cb|
|
@@ -147,10 +148,10 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
147
148
|
test "empty query with selected collection should return all collection members" do
|
148
149
|
visit search_path(:lang => 'en', :format => 'html')
|
149
150
|
|
150
|
-
select "Labels"
|
151
|
-
select "exact match"
|
151
|
+
find("#t").select "Labels"
|
152
|
+
find("#qt").select "exact match"
|
152
153
|
fill_in "Search term(s)", :with => ""
|
153
|
-
select @collection.to_s
|
154
|
+
find("#c").select @collection.to_s
|
154
155
|
|
155
156
|
# select all languages
|
156
157
|
page.all(:css, ".lang_check").each do |cb|
|
@@ -175,8 +176,8 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
175
176
|
|
176
177
|
visit search_path(:lang => 'en', :format => 'html')
|
177
178
|
|
178
|
-
select "Labels"
|
179
|
-
select "contains"
|
179
|
+
find("#t").select "Labels"
|
180
|
+
find("#qt").select "contains"
|
180
181
|
fill_in "Search term(s)", :with => "sample_"
|
181
182
|
|
182
183
|
click_button("Search")
|
@@ -184,7 +185,7 @@ class SearchTest < ActionDispatch::IntegrationTest
|
|
184
185
|
assert page.has_css?("#search_results dt", :count => 5)
|
185
186
|
assert page.has_css?(".pagination .page", :count => 3)
|
186
187
|
|
187
|
-
|
188
|
+
find(".pagination").all(".page").last.find("a").click
|
188
189
|
|
189
190
|
assert page.has_css?("#search_results dt", :count => 2)
|
190
191
|
|