diff --git a/app/assets/javascripts/cookies_consent.js b/app/assets/javascripts/cookies_consent.js index 6f37b42ba..898ac7062 100644 --- a/app/assets/javascripts/cookies_consent.js +++ b/app/assets/javascripts/cookies_consent.js @@ -5,14 +5,36 @@ $("#cookies_consent_banner").hide(); $("#cookies_consent_management").foundation("close"); }, + setCookiesConsent: function(id, value) { + document.getElementById(id).checked = value; + }, + vendors: function() { + return $(".cookies-vendors input[type=checkbox]"); + }, initialize: function() { $(".accept-all-cookies").on("click", function() { App.Cookies.saveCookie("cookies_consent", "all", 365); + App.CookiesConsent.vendors().each(function() { + App.Cookies.saveCookie(this.name, true, 365); + App.CookiesConsent.setCookiesConsent(this.id, true); + }); App.CookiesConsent.hide(); }); $(".accept-essential-cookies").on("click", function() { App.Cookies.saveCookie("cookies_consent", "essential", 365); + App.CookiesConsent.vendors().each(function() { + App.Cookies.saveCookie(this.name, false, 365); + App.CookiesConsent.setCookiesConsent(this.id, false); + }); + App.CookiesConsent.hide(); + }); + + $(".save-cookies-preferences").on("click", function() { + App.Cookies.saveCookie("cookies_consent", "custom", 365); + App.CookiesConsent.vendors().each(function() { + App.Cookies.saveCookie(this.name, this.checked, 365); + }); App.CookiesConsent.hide(); }); } diff --git a/app/assets/stylesheets/layout/cookies_consent_management.scss b/app/assets/stylesheets/layout/cookies_consent_management.scss index 1636300a7..290144261 100644 --- a/app/assets/stylesheets/layout/cookies_consent_management.scss +++ b/app/assets/stylesheets/layout/cookies_consent_management.scss @@ -16,29 +16,39 @@ .buttons { border-top: 1px solid $medium-gray; + margin-top: $line-height; padding-top: $line-height; + } - button { + button { + @include breakpoint(small only) { + display: block; + width: 100%; + } + + &.accept-all-cookies, + &.accept-essential-cookies { + @include regular-button; + margin-bottom: 0; + } + + &.accept-all-cookies { @include breakpoint(small only) { - display: block; - width: 100%; + margin-bottom: $line-height / 3; } + } - &.accept-all-cookies, - &.accept-essential-cookies { - @include regular-button; - margin-bottom: 0; - } - - &.accept-all-cookies { - @include breakpoint(small only) { - margin-bottom: $line-height / 3; - } - } + &.save-cookies-preferences { + @include hollow-button; } } - .cookies-essentials { + .save-preferences { + text-align: #{$global-right}; + } + + .cookies-essentials, + .cookies-vendors { ul { list-style: none; margin-#{$global-left}: 0; diff --git a/app/components/layout/cookies_consent/management_component.html.erb b/app/components/layout/cookies_consent/management_component.html.erb index a640fcbd5..6a060c468 100644 --- a/app/components/layout/cookies_consent/management_component.html.erb +++ b/app/components/layout/cookies_consent/management_component.html.erb @@ -24,10 +24,12 @@ + <%= render Layout::CookiesConsent::VendorsComponent.new %> +
<% if vendors.any? %> - <% end %> + <% end %>
diff --git a/app/components/layout/cookies_consent/vendors_component.html.erb b/app/components/layout/cookies_consent/vendors_component.html.erb new file mode 100644 index 000000000..c5ae59985 --- /dev/null +++ b/app/components/layout/cookies_consent/vendors_component.html.erb @@ -0,0 +1,20 @@ +

<%= t("cookies_management.third_party.title") %>

+

<%= t("cookies_management.third_party.description") %>

+ +
+ + +
+ +
+
diff --git a/app/components/layout/cookies_consent/vendors_component.rb b/app/components/layout/cookies_consent/vendors_component.rb new file mode 100644 index 000000000..9b324fe8a --- /dev/null +++ b/app/components/layout/cookies_consent/vendors_component.rb @@ -0,0 +1,11 @@ +class Layout::CookiesConsent::VendorsComponent < Layout::CookiesConsent::BaseComponent + delegate :cookies, :dom_id, to: :helpers + + def render? + super && vendors.any? + end + + def enabled?(vendor) + cookies[vendor.cookie] == "true" + end +end diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 5635ada01..d62b8a1f5 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -943,8 +943,12 @@ en: title: "Cookies policy" cookies_management: title: Cookies management - description: This website uses own for its proper functioning. By clicking the Accept essential cookies button, you agree to the use of these technologies and the processing of your data for these purposes. + description: This website uses own and third party cookies for its proper functioning. By clicking the Accept all button, you agree to the use of these technologies and the processing of your data for these purposes. essentials: title: Essential cookies description: They are used for many different purposes, such as recognising you as a user, choosing the language or customising the way in which content is displayed. hint: Without these, basic navigation functions will be impaired, so they should always be active. + third_party: + title: Third party cookies + description: This website use third-party cookies. These cookies can enhance functionality or collect information to improve your user experience. + save_preferences: Save preferences diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 341001fbe..ff88aca9c 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -943,8 +943,12 @@ es: title: "Política de cookies" cookies_management: title: Configuración de cookies - description: Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer click en el botón Aceptar cookies esenciales, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. + description: Esta web utiliza cookies propias y de terceros para su correcto funcionamiento. Al hacer click en el botón Aceptar todo, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. essentials: title: Cookies esenciales description: Utilizadas para finalidades muy diversas, como por ejemplo, reconocerte como usuario, elegir el idioma o personalizar la forma en la que se muestra el contenido. hint: Sin ellas, las funciones básicas de navegación se verán afectadas, por lo que deben estar siempre activas. + third_party: + title: Cookies de terceros + description: Esta web usa cookies de terceros. Estas cookies pueden recopilar información para mejorar tu experiencia de usuario. + save_preferences: Guardar preferencias diff --git a/spec/components/layout/cookies_consent/management_component_spec.rb b/spec/components/layout/cookies_consent/management_component_spec.rb index 2eb79c925..c92bfd431 100644 --- a/spec/components/layout/cookies_consent/management_component_spec.rb +++ b/spec/components/layout/cookies_consent/management_component_spec.rb @@ -22,6 +22,7 @@ describe Layout::CookiesConsent::ManagementComponent do expect(page).to have_link "More information about cookies", href: "/cookies_policy" expect(page).to have_css "h3", text: "Essential cookies" expect(page).to have_css ".switch-input[type='checkbox'][name='essential_cookies'][disabled][checked]" + expect(page).to have_css "h3", text: "Third party cookies" expect(page).to have_button "Accept all" expect(page).to have_button "Accept essential cookies" end diff --git a/spec/components/layout/cookies_consent/vendors_component_spec.rb b/spec/components/layout/cookies_consent/vendors_component_spec.rb new file mode 100644 index 000000000..5e5f3beee --- /dev/null +++ b/spec/components/layout/cookies_consent/vendors_component_spec.rb @@ -0,0 +1,23 @@ +require "rails_helper" + +describe Layout::CookiesConsent::VendorsComponent do + before { Setting["feature.cookies_consent"] = true } + + it "is not rendered when there are no vendors" do + render_inline Layout::CookiesConsent::VendorsComponent.new + + expect(page).not_to be_rendered + end + + it "renders vendors content when there are vendors" do + create(:cookies_vendor, name: "Vendor cookie", cookie: "third_party") + + render_inline Layout::CookiesConsent::VendorsComponent.new + + expect(page).to be_rendered + expect(page).to have_content "Third party cookies" + expect(page).to have_content "Vendor cookie" + expect(page).to have_css ".switch-input[type='checkbox'][name='third_party']" + expect(page).to have_button "Save preferences" + end +end diff --git a/spec/system/cookies_consent_spec.rb b/spec/system/cookies_consent_spec.rb index f70a9f672..5d18a240e 100644 --- a/spec/system/cookies_consent_spec.rb +++ b/spec/system/cookies_consent_spec.rb @@ -1,19 +1,24 @@ require "rails_helper" describe "Cookies consent" do - before { Setting["feature.cookies_consent"] = true } + before do + Setting["feature.cookies_consent"] = true + create(:cookies_vendor, name: "Third party", cookie: "third_party" ) + end context "Banner consent" do scenario "Hides the banner when accepting essential cookies and for consecutive visits" do visit root_path expect(cookie_by_name("cookies_consent")).to be nil + expect(cookie_by_name("third_party")).to be nil within ".cookies-consent-banner" do click_button "Accept essential cookies" end expect(cookie_by_name("cookies_consent")[:value]).to eq "essential" + expect(cookie_by_name("third_party")[:value]).to eq "false" expect(page).not_to have_content "Cookies policy" refresh @@ -25,12 +30,14 @@ describe "Cookies consent" do visit root_path expect(cookie_by_name("cookies_consent")).to be nil + expect(cookie_by_name("third_party")).to be nil within ".cookies-consent-banner" do click_button "Accept all" end expect(cookie_by_name("cookies_consent")[:value]).to eq "all" + expect(cookie_by_name("third_party")[:value]).to eq "true" expect(page).not_to have_content "Cookies policy" refresh @@ -44,6 +51,7 @@ describe "Cookies consent" do visit root_path expect(cookie_by_name("cookies_consent")).to be nil + expect(cookie_by_name("third_party")).to be nil within ".cookies-consent-banner" do click_button "Manage cookies" @@ -54,6 +62,7 @@ describe "Cookies consent" do end expect(cookie_by_name("cookies_consent")[:value]).to eq "essential" + expect(cookie_by_name("third_party")[:value]).to eq "false" expect(page).not_to have_content "Cookies policy" expect(page).not_to have_content "Cookies management" @@ -66,6 +75,7 @@ describe "Cookies consent" do visit root_path expect(cookie_by_name("cookies_consent")).to be nil + expect(cookie_by_name("third_party")).to be nil within ".cookies-consent-banner" do click_button "Manage cookies" @@ -76,6 +86,35 @@ describe "Cookies consent" do end expect(cookie_by_name("cookies_consent")[:value]).to eq "all" + expect(cookie_by_name("third_party")[:value]).to eq "true" + expect(page).not_to have_content "Cookies policy" + expect(page).not_to have_content "Cookies management" + + refresh + + expect(page).not_to have_content "Cookies policy" + end + + scenario "Allow users to accept custom cookies from the cookies management modal" do + visit root_path + + expect(cookie_by_name("cookies_consent")).to be nil + expect(cookie_by_name("third_party")).to be nil + + within ".cookies-consent-banner" do + click_button "Manage cookies" + end + + within ".cookies-consent-management" do + expect(page).to have_unchecked_field "Third party", visible: :none + find("label[for='third_party']").click + expect(page).to have_checked_field "Third party", visible: :none + + click_button "Save preferences" + end + + expect(cookie_by_name("cookies_consent")[:value]).to eq "custom" + expect(cookie_by_name("third_party")[:value]).to eq "true" expect(page).not_to have_content "Cookies policy" expect(page).not_to have_content "Cookies management"