diff --git a/app/controllers/related_contents_controller.rb b/app/controllers/related_contents_controller.rb new file mode 100644 index 000000000..06bfaadc7 --- /dev/null +++ b/app/controllers/related_contents_controller.rb @@ -0,0 +1,42 @@ +class RelatedContentsController < ApplicationController + VALID_URL = /#{Setting['url']}\/.*\/.*/ + + skip_authorization_check + + def create + if relationable_object && related_object + @relationable.relate_content(@related) + + flash[:success] = t('related_content.success') + else + flash[:error] = t('related_content.error', url: Setting['url']) + end + + redirect_to @relationable + end + + private + + def valid_url? + params[:url].match(VALID_URL) + end + + def relationable_object + @relationable = (params[:relationable_klass].singularize.camelize.constantize).find_by_id(params[:relationable_id]) + end + + def related_object + begin + if valid_url? + url = params[:url] + + related_klass = url.match(/\/(#{RelatedContent::RELATIONABLE_MODELS.join("|")})\//)[0].gsub("/", "") + related_id = url.match(/\/[0-9]+/)[0].gsub("/", "") + + @related = (related_klass.singularize.camelize.constantize).find_by_id(related_id) + end + rescue + nil + end + end +end diff --git a/app/models/related_content.rb b/app/models/related_content.rb index ab72aefe3..fa41a57ad 100644 --- a/app/models/related_content.rb +++ b/app/models/related_content.rb @@ -1,5 +1,6 @@ class RelatedContent < ActiveRecord::Base RELATED_CONTENTS_REPORT_THRESHOLD = Setting['related_contents_report_threshold'].to_i + RELATIONABLE_MODELS = %w{proposals debates} belongs_to :parent_relationable, polymorphic: true belongs_to :child_relationable, polymorphic: true diff --git a/app/views/relationable/_form.html.erb b/app/views/relationable/_form.html.erb new file mode 100644 index 000000000..930c839a2 --- /dev/null +++ b/app/views/relationable/_form.html.erb @@ -0,0 +1,22 @@ +<%= form_tag related_contents_path, method: :post, id: "related_content", class: "hide", "data-toggler": ".hide" do %> + + + + +
+
+ <%= text_field_tag :url, '', + "aria-describedby": "related_content_help_text", + placeholder: t("related_content.placeholder", url: setting['url']) %> + + <%= hidden_field_tag :relationable_klass, relationable.class.name %> + <%= hidden_field_tag :relationable_id, relationable.id %> +
+ +
+ <%= submit_tag t("related_content.submit"), class: "button" %> +
+
+ <% end %> diff --git a/app/views/relationable/_related_content.html.erb b/app/views/relationable/_related_content.html.erb index e780d3cf7..19435fec2 100644 --- a/app/views/relationable/_related_content.html.erb +++ b/app/views/relationable/_related_content.html.erb @@ -4,12 +4,15 @@

<%= t("related_content.title") %> (<%= relationable.relationed_contents.count %>)

- - - <%= t("related_content.add") %> + + + <%= render 'relationable/form', relationable: relationable %> + <%= render 'relationable/related_list', relationable: relationable %> diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index aad6031a8..3391bc3fd 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -817,7 +817,7 @@ en: add: "Add related content" label: "Link to related content" placeholder: "%{url}" - help: "You can add any link inside of %{org}." + help: "You can add links of %{models} inside of %{org}." submit: "Add" error: "Link not valid. Remember to start with %{url}." success: "You added a new related content" diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 15a29856f..db290316c 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -814,7 +814,7 @@ es: add: "Añadir contenido relacionado" label: "Enlace a contenido relacionado" placeholder: "%{url}" - help: "Puedes introducir cualquier enlace que esté dentro de %{org}." + help: "Puedes introducir cualquier enlace de %{models} que esté dentro de %{org}." submit: "Añadir" error: "Enlace no válido. Recuerda que debe empezar por %{url}." success: "Has añadido un nuevo contenido relacionado" diff --git a/config/routes.rb b/config/routes.rb index 31d811293..429e5a862 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -462,6 +462,8 @@ Rails.application.routes.draw do root to: "dashboard#index" end + resources :related_contents, only: [:create] + # GraphQL get '/graphql', to: 'graphql#query' post '/graphql', to: 'graphql#query' diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index e9c5dbd6d..9f64abd40 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -139,6 +139,57 @@ feature 'Proposals' do expect(page).to have_content(proposal1.title) end end + + scenario 'related contents can be added' do + proposal1 = create(:proposal) + proposal2 = create(:proposal) + debate1 = create(:debate) + + visit proposal_path(proposal1) + + expect(page).to have_selector('#related_content', visible: false) + click_on("Add related content") + expect(page).to have_selector('#related_content', visible: true) + + within("#related_content") do + fill_in 'url', with: "#{Setting['url']}/proposals/#{proposal2.to_param}" + click_button "Add" + end + + within("#related-content-list") do + expect(page).to have_content(proposal2.title) + end + + visit proposal_path(proposal2) + + within("#related-content-list") do + expect(page).to have_content(proposal1.title) + end + + within("#related_content") do + fill_in 'url', with: "#{Setting['url']}/debates/#{debate1.to_param}" + click_button "Add" + end + + within("#related-content-list") do + expect(page).to have_content(debate1.title) + end + end + + scenario 'if related content URL is invalid returns error' do + proposal1 = create(:proposal) + + visit proposal_path(proposal1) + + click_on("Add related content") + + within("#related_content") do + fill_in 'url', with: "http://invalidurl.com" + click_button "Add" + end + + expect(page).to have_content("Link not valid. Remember to start with #{Setting[:url]}.") + end end context "Embedded video" do