iqvoc 4.0.9 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +8 -6
  4. data/Gemfile.lock +56 -36
  5. data/README.md +3 -7
  6. data/app/controllers/concepts/hierarchical_controller.rb +2 -5
  7. data/app/controllers/concepts/scheme_controller.rb +51 -0
  8. data/app/controllers/concepts_controller.rb +2 -0
  9. data/app/controllers/hierarchy_controller.rb +105 -0
  10. data/app/controllers/rdf_controller.rb +0 -10
  11. data/app/controllers/user_sessions_controller.rb +5 -1
  12. data/app/helpers/application_helper.rb +1 -1
  13. data/app/helpers/concepts_helper.rb +19 -0
  14. data/app/helpers/rdf_helper.rb +5 -0
  15. data/app/models/concept/base.rb +10 -1
  16. data/app/models/concept/relation/skos/base.rb +8 -1
  17. data/app/models/concept/skos/scheme.rb +54 -13
  18. data/app/models/concept/validations.rb +2 -2
  19. data/app/models/labeling/base.rb +8 -0
  20. data/app/models/labeling/skos/base.rb +0 -8
  21. data/app/models/notation/base.rb +59 -0
  22. data/app/views/concepts/_form.html.erb +9 -1
  23. data/app/views/concepts/scheme/_sidebar.html.erb +6 -0
  24. data/app/views/concepts/scheme/edit.html.erb +30 -0
  25. data/app/views/concepts/scheme/show.html.erb +19 -0
  26. data/app/views/{rdf/scheme.iqrdf → concepts/scheme/show.iqrdf} +0 -0
  27. data/app/views/hierarchy/show.html.erb +5 -0
  28. data/app/views/hierarchy/show.iqrdf +24 -0
  29. data/app/views/partials/notation/_base.html.erb +8 -0
  30. data/app/views/partials/notation/_edit_base.html.erb +18 -0
  31. data/config/application.rb +2 -0
  32. data/config/engine.rb +0 -1
  33. data/config/initializers/mime_types.rb +2 -2
  34. data/config/locales/activerecord.de.yml +8 -0
  35. data/config/locales/activerecord.en.yml +8 -0
  36. data/config/locales/activerecord.pt.yml +8 -0
  37. data/config/locales/de.yml +5 -1
  38. data/config/locales/en.yml +5 -1
  39. data/config/locales/pt.yml +5 -1
  40. data/config/routes.rb +35 -32
  41. data/db/migrate/20130315093255_add_notations.rb +9 -0
  42. data/db/migrate/20130315141952_add_indexes_to_notations.rb +5 -0
  43. data/db/schema.rb +9 -1
  44. data/iqvoc.gemspec +0 -1
  45. data/lib/generators/app/template.rb +3 -0
  46. data/lib/iqvoc/ability.rb +3 -1
  47. data/lib/iqvoc/configuration/concept.rb +10 -1
  48. data/lib/iqvoc/configuration/core.rb +4 -0
  49. data/lib/iqvoc/rdfapi.rb +1 -0
  50. data/lib/iqvoc/skos_importer.rb +14 -7
  51. data/lib/iqvoc/version.rb +1 -1
  52. data/test/functional/hierarchy_test.rb +355 -0
  53. data/test/integration/client_edit_concept_test.rb +1 -1
  54. data/test/integration/concept_scheme_test.rb +38 -5
  55. data/test/unit/concept_scheme_test.rb +35 -0
  56. data/test/unit/skos_import_test.rb +29 -2
  57. metadata +40 -64
data/db/schema.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20130227145825) do
14
+ ActiveRecord::Schema.define(:version => 20130315141952) do
15
15
 
16
16
  create_table "collection_members", :force => true do |t|
17
17
  t.integer "collection_id"
@@ -92,6 +92,14 @@ ActiveRecord::Schema.define(:version => 20130227145825) do
92
92
  add_index "matches", ["concept_id", "type"], :name => "ix_matches_fk_type"
93
93
  add_index "matches", ["type"], :name => "ix_matches_on_type"
94
94
 
95
+ create_table "notations", :force => true do |t|
96
+ t.integer "concept_id"
97
+ t.string "value", :limit => 4000
98
+ t.string "data_type", :limit => 4000
99
+ end
100
+
101
+ add_index "notations", ["concept_id"], :name => "index_notations_on_concept_id"
102
+
95
103
  create_table "note_annotations", :force => true do |t|
96
104
  t.integer "note_id"
97
105
  t.string "predicate", :limit => 50
data/iqvoc.gemspec CHANGED
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
20
20
  s.add_dependency 'iq_rdf', '~> 0.1.2'
21
21
  s.add_dependency 'json'
22
22
  s.add_dependency 'rails_autolink'
23
- s.add_dependency 'fastercsv'
24
23
  s.add_dependency 'simple_form'
25
24
  s.add_dependency 'sass-rails', '~> 3.2.5'
26
25
  s.add_dependency 'iq_triplestorage'
@@ -11,6 +11,9 @@ gem 'iqvoc'
11
11
  gsub_file file, app_const_base, namespaced_app_name
12
12
  end
13
13
 
14
+ gsub_file "config/application.rb", /filter_parameters .*:password\b/,
15
+ '\0, :password_confirmation'
16
+
14
17
  gsub_file "config/routes.rb", "#{app_const_base}::Application", "Rails.application"
15
18
 
16
19
  %w(development test production).each do |env|
data/lib/iqvoc/ability.rb CHANGED
@@ -31,7 +31,7 @@ module Iqvoc
31
31
  can :merge, [::Concept::Base, ::Label::Base], :published_at => nil
32
32
  end
33
33
 
34
- if user.owns_role?(:administrator) # Admins ...
34
+ if user.owns_role?(:administrator)
35
35
  can [:update, :destroy, :unlock], [::Concept::Base, ::Label::Base], :published_at => nil # Mustn't be locked by myself
36
36
 
37
37
  can :manage, User
@@ -39,6 +39,8 @@ module Iqvoc
39
39
 
40
40
  can :full_export, ::Concept::Base
41
41
  can :import, ::Concept::Base
42
+
43
+ can :update, Iqvoc::Concept.root_class.instance
42
44
  end
43
45
  else # no user
44
46
  can :create, UserSession
@@ -13,6 +13,7 @@ module Iqvoc
13
13
  :pref_labeling_class_name,
14
14
  :match_class_names,
15
15
  :note_class_names,
16
+ :notation_class_names,
16
17
  :additional_association_class_names,
17
18
  :view_sections,
18
19
  :include_module_names
@@ -42,9 +43,13 @@ module Iqvoc
42
43
  'Match::SKOS::NarrowMatch',
43
44
  ]
44
45
 
46
+ self.notation_class_names = [
47
+ 'Notation::Base'
48
+ ]
49
+
45
50
  self.additional_association_class_names = {}
46
51
 
47
- self.view_sections = ["main", "labels", "relations", "notes", "matches"]
52
+ self.view_sections = ["main", "labels", "relations", "notes", "notations", "matches"]
48
53
 
49
54
  self.include_module_names = []
50
55
  end
@@ -122,6 +127,10 @@ module Iqvoc
122
127
  match_class_names.map(&:constantize)
123
128
  end
124
129
 
130
+ def notation_classes
131
+ notation_class_names.map(&:constantize)
132
+ end
133
+
125
134
  def additional_association_classes
126
135
  additional_association_class_names.keys.each_with_object({}) do |class_name, hash|
127
136
  hash[class_name.constantize] = additional_association_class_names[class_name]
@@ -24,6 +24,10 @@ module Iqvoc
24
24
  :content => proc { link_to "Dashboard", dashboard_path },
25
25
  :controller => "dashboard",
26
26
  :authorized? => proc { can? :use, :dashboard }
27
+ }, {
28
+ :content => proc { link_to "Scheme", scheme_path },
29
+ :controller => "concepts/scheme",
30
+ :authorized? => proc { can? :read, Iqvoc::Concept.root_class.instance }
27
31
  }, {
28
32
  :content => proc { link_to ::Concept::Base.model_name.human(:count => 2),
29
33
  hierarchical_concepts_path },
data/lib/iqvoc/rdfapi.rb CHANGED
@@ -21,6 +21,7 @@ module Iqvoc
21
21
  Iqvoc::Concept.note_classes +
22
22
  Iqvoc::Concept.relation_classes +
23
23
  Iqvoc::Concept.match_classes +
24
+ Iqvoc::Concept.notation_classes +
24
25
  [Iqvoc::Collection.member_class]
25
26
 
26
27
  OBJECT_DICTIONARY = FIRST_LEVEL_OBJECT_CLASSES.inject({}) do |hash, klass|
@@ -8,6 +8,8 @@ module Iqvoc
8
8
  Iqvoc::Concept.note_classes +
9
9
  Iqvoc::Concept.relation_classes +
10
10
  Iqvoc::Concept.match_classes +
11
+ Iqvoc::Concept.notation_classes +
12
+ [Iqvoc::Concept.root_class] +
11
13
  [Iqvoc::Collection.member_class]
12
14
 
13
15
  def initialize(file, default_namespace_url, logger = Rails.logger)
@@ -30,6 +32,11 @@ module Iqvoc
30
32
  end
31
33
 
32
34
  @seen_first_level_objects = {} # Concept cache (don't load any concept twice from db)
35
+
36
+ # Assign the default concept scheme singleton instance as a seen first level object upfront
37
+ # in order to handle a missing scheme definition in ntriple data
38
+ @seen_first_level_objects[Iqvoc::Concept.root_class.instance.origin] = Iqvoc::Concept.root_class.instance
39
+
33
40
  @new_subjects = [] # Concepts to be published later
34
41
 
35
42
  # Triples the importer doesn't understand immediately. Example:
@@ -37,7 +44,7 @@ module Iqvoc
37
44
  # :a skos:prefLabel "foo". # => What is :a? Remember this and try again later
38
45
  # ....
39
46
  # :a rdf:type skos:Concept # => Now I know :a, good I remebered it's prefLabel...
40
- @unknown_second_level_tripes = []
47
+ @unknown_second_level_triples = []
41
48
 
42
49
  # Hash of arrays of arrays: { "_:n123" => [["pred1", "obj1"], ["pred2", "obj2"]] }
43
50
  @blank_nodes = {}
@@ -75,7 +82,7 @@ module Iqvoc
75
82
  end
76
83
 
77
84
  @logger.debug("Computing 'forward' defined triples...")
78
- @unknown_second_level_tripes.each do |s, p, o|
85
+ @unknown_second_level_triples.each do |s, p, o|
79
86
  import_second_level_objects(second_level_types, true, s, p, o)
80
87
  end
81
88
 
@@ -145,7 +152,7 @@ module Iqvoc
145
152
  if final
146
153
  @logger.warn "Iqvoc::SkosImporter: Couldn't find Subject with origin '#{subject_origin}. Skipping entry '#{subject} #{predicate} #{object}.'"
147
154
  else
148
- @unknown_second_level_tripes << initial_triple
155
+ @unknown_second_level_triples << initial_triple
149
156
  end
150
157
  return false
151
158
  end
@@ -156,9 +163,9 @@ module Iqvoc
156
163
  object = load_first_level_object(object_origin)
157
164
  unless object
158
165
  if final
159
- @logger.warn "Iqvoc::SkosImporter: Couldn't find Object with origin '#{object_origin}. Skipping entry ':#{subject_origin} #{predicate} #{object}.'"
166
+ @logger.warn "Iqvoc::SkosImporter: Couldn't find Object with origin '#{object_origin}'. Skipping entry ':#{subject_origin} #{predicate} #{object}.'"
160
167
  else
161
- @unknown_second_level_tripes << initial_triple
168
+ @unknown_second_level_triples << initial_triple
162
169
  end
163
170
  return false
164
171
  end
@@ -174,7 +181,7 @@ module Iqvoc
174
181
  if final
175
182
  object = @blank_nodes[object]
176
183
  else
177
- @unknown_second_level_tripes << initial_triple
184
+ @unknown_second_level_triples << initial_triple
178
185
  return false
179
186
  end
180
187
  end
@@ -205,7 +212,7 @@ module Iqvoc
205
212
 
206
213
  triple.each do |e| # Do some fun with the uris and literals
207
214
  @prefixes.keys.each do |uri_prefix| # Use prefixes instead of full uris
208
- e.gsub! /<#{uri_prefix}([^>]*)>/ do |matches|
215
+ e.gsub! /^<#{uri_prefix}([^>]*)>/ do |matches|
209
216
  @prefixes[uri_prefix] + $1.gsub(".", "_")
210
217
  end
211
218
  end
data/lib/iqvoc/version.rb CHANGED
@@ -15,5 +15,5 @@
15
15
  # limitations under the License.
16
16
 
17
17
  module Iqvoc
18
- VERSION = "4.0.9"
18
+ VERSION = "4.1.0"
19
19
  end
@@ -0,0 +1,355 @@
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
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../test_helper')
18
+
19
+ class HierarchyTest < ActionController::TestCase
20
+
21
+ setup do
22
+ @controller = HierarchyController.new
23
+
24
+ # create a concept hierarchy
25
+
26
+ concepts = YAML.load <<-EOS
27
+ root:
28
+ foo:
29
+ bar:
30
+ alpha:
31
+ bravo:
32
+ uno:
33
+ dos:
34
+ lorem:
35
+ ipsum:
36
+ EOS
37
+ rel_class = Iqvoc::Concept.broader_relation_class.narrower_class
38
+ @concepts = create_hierarchy(concepts, rel_class, {})
39
+ @concepts["root"].update_attribute("top_term", true)
40
+ end
41
+
42
+ test "caching" do
43
+ params = { :lang => "en", :format => "ttl", :root => "root" }
44
+
45
+ # ETag generation & cache control
46
+
47
+ get :show, params
48
+ etag = @response.headers["ETag"]
49
+ assert_response 200
50
+ assert etag
51
+ assert @response.headers["Cache-Control"].include?("public")
52
+
53
+ get :show, params
54
+ assert_response 200
55
+ assert_equal etag, @response.headers["ETag"]
56
+
57
+ get :show, params.merge(:published => "0")
58
+ assert_response 200
59
+ assert @response.headers["Cache-Control"].include?("private")
60
+
61
+ # ETag keyed on params
62
+
63
+ get :show, params.merge(:depth => 4)
64
+ assert_response 200
65
+ assert_not_equal etag, @response.headers["ETag"]
66
+
67
+ get :show, params.merge(:published => 0)
68
+ assert_response 200
69
+ assert_not_equal etag, @response.headers["ETag"]
70
+
71
+ # ETag keyed on (any in-scope) concept modification
72
+
73
+ t0 = Time.now
74
+ t1 = Time.now + 30
75
+
76
+ dummy = create_concept("dummy", "Dummy", "en", false)
77
+ dummy.update_attribute("updated_at", t1)
78
+ get :show, params
79
+ assert_response 200
80
+ assert_equal etag, @response.headers["ETag"]
81
+
82
+ dummy.update_attribute("published_at", t0)
83
+ dummy.update_attribute("updated_at", t1)
84
+ get :show, params
85
+ assert_response 200
86
+ new_etag = @response.headers["ETag"]
87
+ assert_not_equal etag, new_etag
88
+
89
+ # conditional caching
90
+
91
+ @request.env["HTTP_IF_NONE_MATCH"] = new_etag
92
+ get :show, params
93
+ assert_response 304
94
+ assert_equal 0, @response.body.strip.length
95
+
96
+ @request.env["HTTP_IF_NONE_MATCH"] = "dummy"
97
+ get :show, params
98
+ assert_response 200
99
+ end
100
+
101
+ test "unsupported content type" do
102
+ get :show, :lang => "en", :format => "N/A", :root => "root"
103
+ assert_response 406
104
+ end
105
+
106
+ test "RDF representations" do
107
+ # Turtle
108
+
109
+ get :show, :lang => "en", :format => "ttl", :root => "root"
110
+ assert_response 200
111
+ assert_equal @response.content_type, "text/turtle"
112
+ assert @response.body.include?(<<-EOS)
113
+ :root a skos:Concept;
114
+ skos:topConceptOf :scheme;
115
+ skos:prefLabel "Root"@en;
116
+ skos:narrower :foo;
117
+ skos:narrower :bar.
118
+ EOS
119
+ assert @response.body.include?(<<-EOS)
120
+ :foo a skos:Concept;
121
+ skos:prefLabel "Foo"@en.
122
+ EOS
123
+ assert @response.body.include?(<<-EOS)
124
+ :bar a skos:Concept;
125
+ skos:prefLabel "Bar"@en;
126
+ skos:narrower :alpha;
127
+ skos:narrower :bravo.
128
+ EOS
129
+ assert @response.body.include?(<<-EOS)
130
+ :alpha a skos:Concept;
131
+ skos:prefLabel "Alpha"@en.
132
+ EOS
133
+ assert @response.body.include?(<<-EOS)
134
+ :bravo a skos:Concept;
135
+ skos:prefLabel "Bravo"@en;
136
+ skos:narrower :uno;
137
+ skos:narrower :dos.
138
+ EOS
139
+ assert @response.body.include?(<<-EOS)
140
+ :uno a skos:Concept;
141
+ skos:prefLabel "Uno"@en.
142
+ EOS
143
+ assert @response.body.include?(<<-EOS)
144
+ :dos a skos:Concept;
145
+ skos:prefLabel "Dos"@en.
146
+ EOS
147
+
148
+ get :show, :lang => "en", :format => "ttl", :root => "lorem", :dir => "up"
149
+ assert_response 200
150
+ assert_equal @response.content_type, "text/turtle"
151
+ assert @response.body.include?(<<-EOS)
152
+ :lorem a skos:Concept;
153
+ skos:prefLabel "Lorem"@en;
154
+ skos:broader :dos.
155
+ EOS
156
+ assert @response.body.include?(<<-EOS)
157
+ :lorem a skos:Concept;
158
+ skos:prefLabel "Lorem"@en;
159
+ skos:broader :dos.
160
+ EOS
161
+ assert @response.body.include?(<<-EOS)
162
+ :dos a skos:Concept;
163
+ skos:prefLabel "Dos"@en;
164
+ skos:broader :bravo.
165
+ EOS
166
+ assert @response.body.include?(<<-EOS)
167
+ :bravo a skos:Concept;
168
+ skos:prefLabel "Bravo"@en;
169
+ skos:broader :bar.
170
+ EOS
171
+ assert @response.body.include?(<<-EOS)
172
+ :bar a skos:Concept;
173
+ skos:prefLabel "Bar"@en.
174
+ EOS
175
+
176
+ # RDF/XML
177
+
178
+ get :show, :lang => "en", :format => "rdf", :root => "root"
179
+ assert_response 200
180
+ assert_equal @response.content_type, "application/rdf+xml"
181
+ end
182
+
183
+ test "root parameter handling" do
184
+ assert_raises(ActionController::RoutingError) do
185
+ get :show, :format => "html"
186
+ end
187
+
188
+ get :show, :lang => "en", :format => "html", :root => "N/A"
189
+ assert_response 404
190
+ assert_equal flash[:error], "no concept matching root parameter"
191
+ entries = css_select("ul.concept-hierarchy li")
192
+ assert_equal entries.length, 0
193
+
194
+ get :show, :lang => "en", :format => "html", :root => "root"
195
+ assert_response 200
196
+ assert_equal flash[:error], nil
197
+ entries = get_entries("ul.concept-hierarchy li")
198
+ assert_equal entries.length, 1
199
+ assert_equal entries[0], "Root"
200
+
201
+ get :show, :lang => "en", :format => "html", :root => "root"
202
+ entries = get_entries("ul.concept-hierarchy li")
203
+ assert_equal entries, ["Root"]
204
+ entries = get_entries("ul.concept-hierarchy li li")
205
+ assert_equal entries, ["Foo", "Bar"]
206
+ entries = get_entries("ul.concept-hierarchy li li li")
207
+ assert_equal entries, ["Alpha", "Bravo"]
208
+ entries = get_entries("ul.concept-hierarchy li li li li")
209
+ assert_equal entries, ["Uno", "Dos"]
210
+ entries = css_select("ul.concept-hierarchy li li li li li")
211
+ assert_equal entries.length, 0 # exceeded default depth
212
+
213
+ get :show, :lang => "en", :format => "html", :root => "bravo"
214
+ entries = get_entries("ul.concept-hierarchy li")
215
+ assert_equal entries, ["Bravo"]
216
+ entries = get_entries("ul.concept-hierarchy li li")
217
+ assert_equal entries, ["Uno", "Dos"]
218
+ entries = get_entries("ul.concept-hierarchy li li li")
219
+ assert_equal entries, ["Lorem", "Ipsum"]
220
+ entries = css_select("ul.concept-hierarchy li li li li")
221
+ assert_equal entries.length, 0
222
+
223
+ get :show, :lang => "en", :format => "html", :root => "lorem"
224
+ entries = get_entries("ul.concept-hierarchy li")
225
+ assert_equal entries, ["Lorem"]
226
+ entries = css_select("ul.concept-hierarchy li li")
227
+ assert_equal entries.length, 0
228
+ end
229
+
230
+ test "depth handling" do
231
+ selector = "ul.concept-hierarchy li li li li li"
232
+
233
+ get :show, :lang => "en", :format => "html", :root => "root"
234
+ entries = css_select(selector)
235
+ assert_equal entries.length, 0 # default depth is 3
236
+
237
+ get :show, :lang => "en", :format => "html", :root => "root", :depth => 4
238
+ entries = css_select(selector)
239
+ assert_equal entries.length, 2
240
+
241
+ get :show, :lang => "en", :format => "html", :root => "root", :depth => 1
242
+ entries = get_entries("ul.concept-hierarchy li")
243
+ assert_equal entries, ["Root"]
244
+ entries = get_entries("ul.concept-hierarchy li li")
245
+ assert_equal entries, ["Foo", "Bar"]
246
+ entries = css_select("ul.concept-hierarchy li li li")
247
+ assert_equal entries.length, 0
248
+
249
+ get :show, :lang => "en", :format => "html", :root => "root", :depth => "invalid"
250
+ assert_response 400
251
+ assert_equal flash[:error], "invalid depth parameter"
252
+ end
253
+
254
+ test "direction handling" do
255
+ get :show, :lang => "en", :format => "html", :root => "root"
256
+ entries = get_entries("ul.concept-hierarchy li")
257
+ assert_equal entries, ["Root"]
258
+ entries = get_entries("ul.concept-hierarchy li li li li")
259
+ assert_equal entries, ["Uno", "Dos"]
260
+
261
+ get :show, :lang => "en", :format => "html", :root => "root", :dir => "up"
262
+ entries = get_entries("ul.concept-hierarchy li")
263
+ assert_equal entries, ["Root"]
264
+ entries = css_select("ul.concept-hierarchy li li")
265
+ assert_equal entries.length, 0
266
+
267
+ get :show, :lang => "en", :format => "html", :root => "lorem"
268
+ entries = get_entries("ul.concept-hierarchy li")
269
+ assert_equal entries, ["Lorem"]
270
+ entries = css_select("ul.concept-hierarchy li li")
271
+ assert_equal entries.length, 0
272
+
273
+ get :show, :lang => "en", :format => "html", :root => "lorem", :dir => "up"
274
+ entries = get_entries("ul.concept-hierarchy li")
275
+ assert_equal entries, ["Lorem"]
276
+ entries = get_entries("ul.concept-hierarchy li li li li")
277
+ assert_equal entries, ["Bar"]
278
+ entries = css_select("ul.concept-hierarchy li li li li li")
279
+ assert_equal entries.length, 0
280
+
281
+ get :show, :lang => "en", :format => "html", :root => "lorem", :dir => "up", :depth => 4
282
+ page.all("ul.concept-hierarchy li").
283
+ map { |node| node.native.children.first.text }
284
+ entries = get_entries("ul.concept-hierarchy li li li li li")
285
+ assert_equal entries, ["Root"]
286
+ end
287
+
288
+ test "siblings handling" do
289
+ get :show, :lang => "en", :format => "html", :root => "foo"
290
+ entries = get_all_entries("ul.concept-hierarchy li")
291
+ assert_equal entries, ["Foo"]
292
+
293
+ get :show, :lang => "en", :format => "html", :root => "foo", :siblings => true
294
+ entries = get_all_entries("ul.concept-hierarchy li")
295
+ assert_equal entries, ["Foo", "Bar"]
296
+
297
+ get :show, :lang => "en", :format => "html", :root => "lorem"
298
+ entries = get_all_entries("ul.concept-hierarchy li")
299
+ assert_equal entries, ["Lorem"]
300
+
301
+ get :show, :lang => "en", :format => "html", :root => "lorem", :dir => "up",
302
+ :siblings => true
303
+ entries = get_all_entries("ul.concept-hierarchy li")
304
+ assert_equal entries.length, 8
305
+ ["Lorem", "Ipsum", "Uno", "Dos", "Alpha", "Bravo", "Bar", "Foo"].each do |name|
306
+ assert entries.include?(name), "missing entry: #{name}"
307
+ end
308
+
309
+ get :show, :lang => "en", :format => "html", :root => "lorem", :dir => "up",
310
+ :siblings => true, :depth => 4
311
+ entries = get_all_entries("ul.concept-hierarchy li")
312
+ assert_equal entries.length, 9
313
+ ["Lorem", "Ipsum", "Uno", "Dos", "Alpha", "Bravo", "Bar", "Foo", "Root"].each do |name|
314
+ assert entries.include?(name), "missing entry: #{name}"
315
+ end
316
+ end
317
+
318
+ def get_all_entries(selector)
319
+ return page.all(selector).map { |node| node.native.children.first.text }
320
+ end
321
+
322
+ def get_entries(selector)
323
+ return css_select(selector).map { |node| node.children.first.content }
324
+ end
325
+
326
+ def page # XXX: should not be necessary!?
327
+ return Capybara::Node::Simple.new(@response.body)
328
+ end
329
+
330
+ def create_hierarchy(hash, rel_class, memo=nil, parent=nil)
331
+ hash.each do |origin, children|
332
+ concept = create_concept(origin, origin.capitalize, "en")
333
+ memo[origin] = concept if memo
334
+ link_concepts(parent, rel_class, concept) if parent
335
+ create_hierarchy(children, rel_class, memo, concept) unless children.blank?
336
+ end
337
+ return memo
338
+ end
339
+
340
+ def link_concepts(source, rel_class, target)
341
+ rel_name = rel_class.name.to_relation_name
342
+ source.send(rel_name).create_with_reverse_relation(target)
343
+ end
344
+
345
+ def create_concept(origin, pref_label, label_lang, published=true)
346
+ concept = Iqvoc::Concept.base_class.create(:origin => origin,
347
+ :published_at => (published ? Time.now : nil))
348
+ label = Iqvoc::Label.base_class.create(:value => pref_label,
349
+ :language => label_lang)
350
+ labeling = Iqvoc::Concept.pref_labeling_class.create(:owner => concept,
351
+ :target => label)
352
+ return concept
353
+ end
354
+
355
+ end
@@ -44,7 +44,7 @@ class ClientEditConceptsTest < ActionDispatch::IntegrationTest
44
44
  assert page.has_css?("#edit_concept")
45
45
 
46
46
  section = page.find("#note_skos_definitions_data")
47
- assert page.has_css?(".note_relation", :count => Iqvoc::Concept.note_class_names.length)
47
+ assert page.has_css?(".note_relation", :count => Iqvoc::Concept.note_class_names.length + Iqvoc::Concept.notation_class_names.length)
48
48
  assert page.has_css?("#note_skos_definitions_data", :count => 1)
49
49
  assert section.has_css?("li", :count => 1)
50
50
 
@@ -14,25 +14,58 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require 'integration_test_helper'
17
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../integration_test_helper')
18
18
 
19
19
  class ConceptSchemeTest < ActionDispatch::IntegrationTest
20
20
 
21
- setup do
21
+ test "list top concepts in rdf scheme" do
22
22
  @concept = FactoryGirl.create(:concept, :broader_relations => [])
23
- end
24
23
 
25
- test "list top concepts in rdf scheme" do
26
24
  visit "/scheme.ttl"
27
25
 
28
26
  assert page.has_content? ":scheme a skos:ConceptScheme"
29
27
  assert page.has_content? "skos:hasTopConcept :#{@concept.origin}"
30
28
  end
31
29
 
32
- test "top terms rdf" do
30
+ test "top concepts rdf" do
31
+ @concept = FactoryGirl.create(:concept, :broader_relations => [])
32
+
33
33
  visit "/#{@concept.origin}.ttl"
34
34
 
35
35
  assert page.has_content? "skos:topConceptOf :scheme"
36
36
  end
37
37
 
38
+ test "non-top-concept in scheme" do
39
+ non_top_concept = FactoryGirl.create(:concept, :broader_relations => [], :top_term => false)
40
+
41
+ visit "/#{non_top_concept.origin}.ttl"
42
+
43
+ assert page.has_content?("skos:inScheme :scheme")
44
+ assert !page.has_content?("skos:topConceptOf :scheme")
45
+ end
46
+
47
+ test "declare top concepts" do
48
+ visit hierarchical_concepts_path(:lang => :en, :format => :html)
49
+
50
+ assert !page.has_link?("Tree 2", :href => "http://www.example.com/en/concepts/foo_1.html")
51
+ assert !page.has_link?("Tree 2", :href => "http://www.example.com/en/concepts/foo_2.html")
52
+
53
+ concept1 = FactoryGirl.create(:concept, :origin => "foo_1", :top_term => false)
54
+ concept2 = FactoryGirl.create(:concept, :origin => "foo_2", :top_term => false)
55
+
56
+ login "administrator"
57
+ visit edit_scheme_path(:lang => :en, :format => :html)
58
+
59
+ fill_in "concept_inline_top_concept_origins",
60
+ :with => [concept1.origin, concept2.origin].join(",")
61
+ click_button "Save"
62
+
63
+ assert page.has_content? "Concept scheme has been saved."
64
+
65
+ visit hierarchical_concepts_path(:lang => :en, :format => :html)
66
+
67
+ assert page.has_link? "Tree 2", :href => "http://www.example.com/en/concepts/foo_1.html"
68
+ assert page.has_link? "Tree 2", :href => "http://www.example.com/en/concepts/foo_2.html"
69
+ end
70
+
38
71
  end
@@ -0,0 +1,35 @@
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
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../test_helper')
18
+
19
+ class ConceptSchemeTest < ActiveSupport::TestCase
20
+ test "singleton concept scheme" do
21
+ assert_equal 0, Concept::SKOS::Scheme.count
22
+
23
+ assert_difference 'Concept::SKOS::Scheme.count' do
24
+ Concept::SKOS::Scheme.instance
25
+ end
26
+
27
+ assert_no_difference 'Concept::SKOS::Scheme.count' do
28
+ Concept::SKOS::Scheme.instance
29
+ end
30
+
31
+ assert_raise TypeError do
32
+ Concept::SKOS::Scheme.create
33
+ end
34
+ end
35
+ end