iqvoc 4.5.2 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +78 -80
  5. data/app/assets/javascripts/iqvoc/concept_mapper.js +15 -7
  6. data/app/assets/javascripts/iqvoc/entityselect.js.erb +11 -1
  7. data/app/assets/javascripts/iqvoc/federated_concept_mapper.js +13 -6
  8. data/app/assets/stylesheets/iqvoc/components/_components.css.scss +12 -1
  9. data/app/concerns/reverse_match_errors.rb +23 -0
  10. data/app/concerns/versioning.rb +1 -1
  11. data/app/controllers/concepts_controller.rb +26 -3
  12. data/app/controllers/rdf_controller.rb +3 -0
  13. data/app/controllers/reverse_matches_controller.rb +73 -0
  14. data/app/jobs/reverse_match_job.rb +57 -0
  15. data/app/models/abstract_user.rb +51 -0
  16. data/app/models/bot_user.rb +25 -0
  17. data/app/models/concept/base.rb +16 -0
  18. data/app/models/job_relation.rb +26 -0
  19. data/app/models/match/skos/broad_match.rb +4 -0
  20. data/app/models/match/skos/close_match.rb +4 -0
  21. data/app/models/match/skos/exact_match.rb +4 -0
  22. data/app/models/match/skos/narrow_match.rb +4 -0
  23. data/app/models/match/skos/related_match.rb +4 -0
  24. data/app/models/note/base.rb +4 -2
  25. data/app/models/services/reverse_match_service.rb +25 -0
  26. data/app/models/user.rb +3 -46
  27. data/app/views/concepts/_form.html.erb +6 -1
  28. data/app/views/concepts/show_published.html.erb +3 -0
  29. data/app/views/concepts/show_unpublished.html.erb +4 -0
  30. data/app/views/partials/concept/_reverse_match_notice.html.erb +25 -0
  31. data/app/views/partials/concept/relation/_edit_base.html.erb +3 -1
  32. data/app/views/partials/concept/relation/_edit_ranked.html.erb +3 -1
  33. data/app/views/partials/note/_search_result.html.erb +1 -1
  34. data/config/locales/de.yml +8 -0
  35. data/config/locales/en.yml +8 -0
  36. data/config/routes.rb +4 -1
  37. data/db/migrate/20140730132113_add_type_to_users.rb +5 -0
  38. data/db/migrate/20140807072457_create_job_relations.rb +11 -0
  39. data/db/migrate/20140807123413_add_response_error_to_job_relation.rb +5 -0
  40. data/iqvoc.gemspec +1 -0
  41. data/lib/iqvoc/ability.rb +8 -0
  42. data/lib/iqvoc/configuration/concept.rb +7 -0
  43. data/lib/iqvoc/version.rb +1 -1
  44. data/lib/tasks/matches.rake +51 -0
  45. data/test/controllers/concept_movement_test.rb +1 -1
  46. data/test/controllers/reverse_match_test.rb +146 -0
  47. data/test/integration/create_concept_test.rb +48 -0
  48. data/test/integration/reverse_match_job_test.rb +111 -0
  49. metadata +33 -1
@@ -0,0 +1,25 @@
1
+ module Services
2
+ class ReverseMatchService
3
+ include Rails.application.routes.url_helpers
4
+
5
+ def initialize(host, port)
6
+ raise ArgumentError if host.empty?
7
+ raise ArgumentError unless port.is_a?(Integer)
8
+ @host = host
9
+ @port = port
10
+ end
11
+
12
+ def build_job(type, origin, subject, match_class)
13
+ raise ArgumentError if type.empty? || origin.empty? || subject.empty? || match_class.empty?
14
+ referer = root_url(host: @host, port: @port)
15
+ object = rdf_url(origin, host: @host, port: @port)
16
+ match_classes = Iqvoc::Concept.reverse_match_class_names
17
+ match_class = match_classes[match_class]
18
+ ReverseMatchJob.new(type, match_class, subject, object, referer, origin)
19
+ end
20
+
21
+ def add(job)
22
+ Delayed::Job.enqueue(job, queue: 'reverse_matches')
23
+ end
24
+ end
25
+ end
data/app/models/user.rb CHANGED
@@ -1,49 +1,6 @@
1
- # encoding: UTF-8
1
+ class User < AbstractUser
2
+ ROLES = ['reader', 'editor', 'publisher', 'administrator']
2
3
 
3
- # Copyright 2011-2013 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
- class User < ActiveRecord::Base
18
- ROLES = [
19
- 'reader', 'editor', 'publisher', 'administrator'
20
- ]
21
-
22
- validates_length_of :forename, :surname, within: 2..255
23
4
  validates_inclusion_of :role, in: ROLES
24
- validates_presence_of :email
25
- validates_uniqueness_of :email
26
- # validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
27
-
28
- acts_as_authentic do |config|
29
- config.validate_email_field = false
30
- config.maintain_sessions = false
31
- config.crypto_provider = Authlogic::CryptoProviders::Sha512 # use authlogic's old crypto provider
32
- end
33
-
34
- def self.default_role
35
- 'reader'
36
- end
37
-
38
- def name
39
- "#{forename} #{surname}"
40
- end
41
-
42
- def owns_role?(name)
43
- self.role == name.to_s
44
- end
45
-
46
- def to_s
47
- self.name.to_s
48
- end
5
+ validates_length_of :forename, :surname, within: 2..255
49
6
  end
@@ -61,8 +61,13 @@
61
61
  <!-- / Concept relations -->
62
62
 
63
63
  <!-- Matches -->
64
- <fieldset class="matches" data-datasets="<%= @datasets %>" data-remote-proxy-url="<%= alphabetical_concepts_path %>" data-translation-other="<%= t('txt.common.other') %>">
64
+ <fieldset <%= 'disabled' unless @concept.published_version.present? %> class="matches" data-datasets="<%= @datasets %>" data-remote-proxy-url="<%= alphabetical_concepts_path %>" data-translation-other="<%= t('txt.common.other') %>" data-no-results-msg="<%= t('txt.views.search_results.no_results') %>">
65
65
  <legend><%= Match::Base.model_name.human(:count => 2) %></legend>
66
+ <% unless @concept.published_version.present? %>
67
+ <%= alert :info do %>
68
+ <%= t('txt.views.concepts.disabled_matches_form_message') %>
69
+ <% end %>
70
+ <% end %>
66
71
  <% Iqvoc::Concept.match_classes.each do |match_class| %>
67
72
  <%= render match_class.edit_partial_name(concept), :owner_klass => concept, :assoc_klass => match_class, :f => f %>
68
73
  <% end %>
@@ -2,6 +2,9 @@
2
2
  <%= render 'concepts/sidebars/singular', :concept => @concept %>
3
3
 
4
4
  <% if @new_concept_version.blank? && can?(:branch, @concept) %>
5
+ <% if @jobs.any? %>
6
+ <%= render partial: 'partials/concept/reverse_match_notice', locals: {concept: @concept, jobs: @jobs} %>
7
+ <% end %>
5
8
  <div class="editing_versioning_toolbar well">
6
9
  <%= button_to t("txt.views.versioning.versioning_mode"),
7
10
  concept_versions_branch_path(:origin => @concept.origin), :class => "btn btn-default" %>
@@ -8,6 +8,10 @@
8
8
  <% end %>
9
9
  <% end %>
10
10
 
11
+ <% if @jobs.any? %>
12
+ <%= render partial: 'partials/concept/reverse_match_notice', locals: {concept: @concept, jobs: @jobs} %>
13
+ <% end %>
14
+
11
15
  <div class="editing_versioning_toolbar well">
12
16
  <% if (not @concept.locked?) || @concept.locked_by == @current_user.id %>
13
17
  <%= button_to t("txt.views.versioning.publishing"),
@@ -0,0 +1,25 @@
1
+ <%# binding.pry %>
2
+ <%= alert :warning, :header => t('txt.views.concepts.pending_jobs_header') + "." do %>
3
+ <%= t("txt.views.concepts.pending_jobs_message") %>
4
+ <ol>
5
+ <% jobs.each do |j| %>
6
+ <li>
7
+ <% if j[:type] == :remove_match %>
8
+ <%= t("txt.views.concepts.remove_match") %>
9
+ <% else %>
10
+ <%= t("txt.views.concepts.add_match") %>
11
+ <% end %>
12
+
13
+ <%= t("txt.views.concepts.job_detail",
14
+ match_class: j[:match_class],
15
+ subject: link_to(j[:subject], j[:subject], class: 'unlabeled'),
16
+ target: link_to(concept, concept_path(concept))
17
+ ).html_safe
18
+ %>
19
+ <% if j[:response_error] %>
20
+ <%= t("txt.views.concepts.job_state", state: j[:response_error]) %>
21
+ <% end %>
22
+ </li>
23
+ <% end %>
24
+ </ol>
25
+ <% end %>
@@ -7,5 +7,7 @@
7
7
  :exclude_top_terms => klass != Iqvoc::Concept.broader_relation_class || nil),
8
8
  :"data-entity-uri" => concept_path("{id}"),
9
9
  :"data-singular" => klass.singular? || nil,
10
- :"data-entities" => widget_entities(concept, klass) %>
10
+ :"data-entities" => widget_entities(concept, klass),
11
+ :'data-no-results-msg' => t('txt.views.search_results.no_results')
12
+ %>
11
13
  <% end %>
@@ -8,5 +8,7 @@
8
8
  :"data-entity-uri" => concept_path("{id}"),
9
9
  :"data-singular" => klass.singular? || nil,
10
10
  :"data-entities" => widget_entities_ranked(concept, klass),
11
- :"data-qualified" => "rank" %>
11
+ :"data-qualified" => "rank",
12
+ :'data-no-results-msg' => t('txt.views.search_results.no_results')
13
+ %>
12
14
  <% end %>
@@ -6,6 +6,6 @@
6
6
  <% end %>
7
7
  <dl class="search-result-meta">
8
8
  <dt class="search-result-key"><%= t('txt.views.search_results.type') %></dt>
9
- <dd class="search-result-value"><%= result.class.model_name.human %></dd>
9
+ <dd class="search-result-value"><%= result.model_name.human %></dd>
10
10
  </dl>
11
11
  </li>
@@ -45,6 +45,7 @@ de:
45
45
  txt:
46
46
  common:
47
47
  iqvoc_title: "iQvoc Vocabulary Management System"
48
+ concept: "Konzept"
48
49
  pref_label: "Bevorzugtes Label"
49
50
  edit: "Bearbeiten"
50
51
  value: "Wert"
@@ -126,6 +127,13 @@ de:
126
127
  new: "Neues %{concept_class_name}"
127
128
  pref_label: "Bevorzugtes Label"
128
129
  classifiers: "Umweltklassen"
130
+ pending_jobs_header: "Austehende Jobs"
131
+ pending_jobs_message: "Zu diesem Konzept existieren noch austehende Jobs."
132
+ disabled_matches_form_message: "Matches können erst nach Veröffentlichung eines Konzepts angelegt werden."
133
+ add_match: "Anlage:"
134
+ remove_match: "Löschung:"
135
+ job_detail: "%{match_class}-Beziehung von Konzept %{subject} aus entfernter Ontologie auf %{target} austehend."
136
+ job_state: "(Status: %{state})"
129
137
  labels:
130
138
  new: "Neues Label"
131
139
  template_form: "Vorlageform"
@@ -45,6 +45,7 @@ en:
45
45
  txt:
46
46
  common:
47
47
  iqvoc_title: "iQvoc Vocabulary Management System"
48
+ concept: "Concept"
48
49
  pref_label: "Preferred label"
49
50
  edit: "Edit"
50
51
  value: "Value"
@@ -128,6 +129,13 @@ en:
128
129
  pref_label: "PrefLabel"
129
130
  close_match: "CloseMatch"
130
131
  classifiers: "Environment classes"
132
+ pending_jobs_header: "Pending jobs"
133
+ pending_jobs_message: "There are pending jobs for this concept."
134
+ disabled_matches_form_message: "A concept have to be published before you can assign mapping properties."
135
+ add_match: "Creation:"
136
+ remove_match: "Deletion:"
137
+ job_detail: "%{match_class}-Relation of concept %{subject} from remote ontology to %{target} pending."
138
+ job_state: "(State: %{state})"
131
139
  labels:
132
140
  new: "New Label"
133
141
  template_form: "Literal form"
data/config/routes.rb CHANGED
@@ -52,7 +52,7 @@ Rails.application.routes.draw do
52
52
  post 'concepts/:origin/to_review' => 'concepts/versions#to_review', as: 'concept_versions_to_review'
53
53
  get 'concepts/:origin/consistency_check' => 'concepts/versions#consistency_check', as: 'concept_versions_consistency_check'
54
54
 
55
- patch 'concepts/:origin/move' => 'concepts#move', as: 'move_concept'
55
+ patch 'concepts/:origin/move' => 'concepts#move', as: 'move_concept'
56
56
 
57
57
  post 'collections/:origin/branch' => 'collections/versions#branch', as: 'collection_versions_branch'
58
58
  post 'collections/:origin/merge' => 'collections/versions#merge', as: 'collection_versions_merge'
@@ -80,6 +80,9 @@ Rails.application.routes.draw do
80
80
  # root to: 'frontpage#index', format: nil
81
81
  end
82
82
 
83
+ patch ':origin/add_match' => 'reverse_matches#add_match', as: 'add_match'
84
+ patch ':origin/remove_match' => 'reverse_matches#remove_match', as: 'remove_match'
85
+
83
86
  get 'remote_labels' => 'remote_labels#show', as: 'remote_label'
84
87
  get 'schema' => redirect('/'), as: 'schema'
85
88
  get 'dataset' => 'rdf#dataset', as: 'rdf_dataset'
@@ -0,0 +1,5 @@
1
+ class AddTypeToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :type, :string
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateJobRelations < ActiveRecord::Migration
2
+ def change
3
+ create_table :job_relations do |t|
4
+ t.string :type
5
+ t.string :owner_reference
6
+ t.string :job_id
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddResponseErrorToJobRelation < ActiveRecord::Migration
2
+ def change
3
+ add_column :job_relations, :response_error, :string
4
+ end
5
+ end
data/iqvoc.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency 'json'
24
24
  s.add_dependency 'rails_autolink'
25
25
  s.add_dependency 'faraday'
26
+ s.add_dependency 'faraday_middleware'
26
27
  s.add_dependency 'sass-rails', '~> 4.0.2'
27
28
  s.add_dependency 'bootstrap-sass', '~> 3.1.1.0'
28
29
  s.add_dependency 'bootstrap_form', '~> 2.1.1'
data/lib/iqvoc/ability.rb CHANGED
@@ -24,6 +24,14 @@ module Iqvoc
24
24
  can :branch, [::Concept::Base, ::Collection::Base, ::Label::Base], &@@if_published
25
25
  end
26
26
 
27
+ if user.owns_role?(:match_editor)
28
+ can :read, ::Concept::Base
29
+ can :create, ::Concept::Base
30
+ can [:update, :lock], ::Concept::Base, locked_by: user.id, published_at: nil
31
+ can :lock, ::Concept::Base, locked_by: nil, published_at: nil
32
+ can :branch, ::Concept::Base, &@@if_published
33
+ end
34
+
27
35
  if user.owns_role?(:publisher) || user.owns_role?(:administrator) # Publishers and above ...
28
36
  can :merge, [::Concept::Base, ::Collection::Base, ::Label::Base], published_at: nil
29
37
  end
@@ -127,6 +127,13 @@ module Iqvoc
127
127
  match_class_names.map(&:constantize)
128
128
  end
129
129
 
130
+ def reverse_match_class_names
131
+ match_class_names.inject({}) do |result, element|
132
+ result[element] = element.parameterize.underscore
133
+ result
134
+ end
135
+ end
136
+
130
137
  def notation_classes
131
138
  notation_class_names.map(&:constantize)
132
139
  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.5.2"
18
+ VERSION = "4.6.0"
19
19
  end
@@ -0,0 +1,51 @@
1
+ namespace :iqvoc do
2
+ namespace :matches do
3
+ stdout_logger = Logger.new(STDOUT)
4
+ stdout_logger.level = Logger::INFO
5
+
6
+ desc 'Create reverse matches jobs for already known matches'
7
+ task :create_jobs => :environment do
8
+ raise "You have to specify the host of the current iqvoc instance. Example: rake iqvoc:matches:create_jobs HOST='http://try.iqvoc.com' PORT='80'" unless ENV['HOST']
9
+ raise "You have to specify the host of the current iqvoc instance. Example: rake iqvoc:matches:create_jobs HOST='http://try.iqvoc.com' PORT='80'" unless ENV['PORT']
10
+
11
+ raise "Error: there are pending reverse match jobs. Clear or process them before." if Delayed::Job.where(queue: 'reverse_matches').any?
12
+
13
+ iqvoc_sources = Iqvoc.config['sources.iqvoc'].map { |s| URI.parse(s) }
14
+ host = ENV['HOST']
15
+ port = ENV['PORT'].to_i
16
+
17
+ reverse_match_service = Services::ReverseMatchService.new(host, port)
18
+
19
+ Match::Base.includes(:concept).find_each do |m|
20
+ target_base_uri = base_uri(m.value)
21
+
22
+ # create jobs if target_base_uri is in iqvoc_sources
23
+ if iqvoc_sources.include?(target_base_uri)
24
+ job = reverse_match_service.build_job(:add_match, m.concept.origin, m.value, m.type)
25
+ reverse_match_service.add(job)
26
+
27
+ stdout_logger.info "Create #{job.match_class}-job: #{job.subject} => #{job.object}"
28
+ else
29
+ stdout_logger.info "#{m.value}: is not a known iQvoc source"
30
+ end
31
+ end
32
+ end
33
+
34
+ desc 'Delete all reverse matches jobs and job relations'
35
+ task :delete_jobs => :environment do
36
+ JobRelation.find_each do |jr|
37
+ jr.job.destroy!
38
+ jr.destroy!
39
+ end
40
+ stdout_logger.info "Cleared Jobs and JobRelations"
41
+ end
42
+
43
+ private
44
+
45
+ def base_uri(url_string)
46
+ target_uri = URI.parse(url_string)
47
+ base_uri = URI.parse("#{target_uri.scheme}://#{target_uri.host}:#{target_uri.port}")
48
+ end
49
+
50
+ end
51
+ end
@@ -27,7 +27,7 @@ class ConceptMovementTest < ActionController::TestCase
27
27
  @admin = User.create! do |u|
28
28
  u.forename = 'Test'
29
29
  u.surname = 'User'
30
- u.email = 'testuser@iqvoc.local'
30
+ u.email = 'admin@iqvoc'
31
31
  u.password = 'omgomgomg'
32
32
  u.password_confirmation = 'omgomgomg'
33
33
  u.role = 'administrator'
@@ -0,0 +1,146 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2011-2014 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 ReverseMatchTest < ActionController::TestCase
20
+
21
+ setup do
22
+ @controller = ReverseMatchesController.new
23
+
24
+ @admin = User.create! do |u|
25
+ u.forename = 'Test'
26
+ u.surname = 'User'
27
+ u.email = 'admin@iqvoc'
28
+ u.password = 'omgomgomg'
29
+ u.password_confirmation = 'omgomgomg'
30
+ u.role = 'administrator'
31
+ u.active = true
32
+ end
33
+
34
+ Iqvoc.config['sources.iqvoc'] = ['http://try.iqvoc.net']
35
+
36
+ @achievement_hobbies = Concept::SKOS::Base.new.tap do |c|
37
+ Iqvoc::RDFAPI.devour c, 'skos:prefLabel', '"Achievement hobbies"@en'
38
+ c.publish
39
+ c.save
40
+ end
41
+
42
+ @airsoft = Concept::SKOS::Base.new.tap do |c|
43
+ Iqvoc::RDFAPI.devour c, 'skos:prefLabel', '"Airsoft"@en'
44
+ c.publish
45
+ c.save
46
+ new_version = c.branch @admin
47
+ new_version.save
48
+ end
49
+
50
+ @request.env['HTTP_ACCEPT'] = 'application/json'
51
+ @request.env['HTTP_REFERER'] = 'http://try.iqvoc.net'
52
+ end
53
+
54
+ teardown do
55
+ Iqvoc.config['sources.iqvoc'] = []
56
+ end
57
+
58
+ test 'remove non existing match' do
59
+ m = Match::SKOS::NarrowMatch.create concept_id: @achievement_hobbies.id, value: 'http://iqvoc.net'
60
+ patch :remove_match,
61
+ origin: @achievement_hobbies.origin,
62
+ match_class: 'match_skos_relatedmatch',
63
+ uri: 'http://iqvoc.net'
64
+ assert_response 400
65
+ body = JSON.parse response.body
66
+ assert_equal body['type'], "unknown_relation"
67
+ end
68
+
69
+ test 'remove match' do
70
+ m = Match::SKOS::NarrowMatch.create concept_id: @achievement_hobbies.id, value: 'http://iqvoc.net'
71
+ patch :remove_match,
72
+ origin: @achievement_hobbies.origin,
73
+ match_class: 'match_skos_broadmatch',
74
+ uri: 'http://iqvoc.net'
75
+ assert_response 200
76
+ body = JSON.parse response.body
77
+ assert_equal body['type'], 'mapping_removed'
78
+
79
+ new_concept_version = Iqvoc::Concept.base_class.by_origin(@achievement_hobbies.origin).last
80
+ assert_equal 2, new_concept_version.rev
81
+ end
82
+
83
+ test 'add match' do
84
+ patch :add_match,
85
+ origin: @achievement_hobbies.origin,
86
+ match_class: 'match_skos_broadmatch',
87
+ uri: 'http://google.de'
88
+ assert_response 200
89
+ body = JSON.parse response.body
90
+ assert_equal body['type'], 'mapping_added'
91
+
92
+ new_concept_version = Iqvoc::Concept.base_class.by_origin(@achievement_hobbies.origin).last
93
+ assert_equal 2, new_concept_version.rev
94
+ end
95
+
96
+ test 'no referer' do
97
+ @request.env['HTTP_REFERER'] = nil
98
+ patch :add_match,
99
+ origin: @achievement_hobbies.origin,
100
+ match_class: 'match_skos_broadmatch',
101
+ uri: 'http://google.de'
102
+ assert_response 400
103
+ body = JSON.parse response.body
104
+ assert_equal body['type'], "no_referer"
105
+ end
106
+
107
+ test 'unknown match class' do
108
+ patch :add_match,
109
+ origin: @achievement_hobbies.origin,
110
+ match_class: 'UnknownMatch',
111
+ uri: 'http://google.de'
112
+ assert_response 400
113
+ body = JSON.parse response.body
114
+ assert_equal body['type'], "unknown_match"
115
+ end
116
+
117
+ test 'unknown referer' do
118
+ @request.env['HTTP_REFERER'] = 'http://iqvoc.net'
119
+ patch :add_match,
120
+ origin: @achievement_hobbies.origin,
121
+ match_class: 'match_skos_broadmatch',
122
+ uri: 'http://iqvoc.net'
123
+ assert_response 403
124
+ body = JSON.parse response.body
125
+ assert_equal body['type'], "unknown_referer"
126
+ end
127
+
128
+ test 'concept with a version' do
129
+ patch :add_match,
130
+ origin: @airsoft.origin,
131
+ match_class: 'match_skos_broadmatch',
132
+ uri: 'http://iqvoc.net'
133
+ assert_response 403
134
+ body = JSON.parse response.body
135
+ assert_equal body['type'], "in_processing"
136
+ end
137
+
138
+ test 'missing parameter' do
139
+ patch :add_match,
140
+ origin: @achievement_hobbies.origin,
141
+ uri: 'http://google.de'
142
+ assert_response 400
143
+ body = JSON.parse response.body
144
+ assert_equal body['type'], "parameter_missing"
145
+ end
146
+ end