Render third party cookies in the management component

Set cookie duration to 365 days based on the AEPD's cookie usage guidelines.

Note from the document: "Cookies with a duration of up to 24 months are
considered acceptable as long as they are periodically updated."
Reference: https://www.aepd.es/guias/guia-cookies.pdf
This commit is contained in:
taitus
2024-12-09 16:28:02 +01:00
parent dc54fda71b
commit 7407c386a6
10 changed files with 155 additions and 19 deletions

View File

@@ -5,14 +5,36 @@
$("#cookies_consent_banner").hide(); $("#cookies_consent_banner").hide();
$("#cookies_consent_management").foundation("close"); $("#cookies_consent_management").foundation("close");
}, },
setCookiesConsent: function(id, value) {
document.getElementById(id).checked = value;
},
vendors: function() {
return $(".cookies-vendors input[type=checkbox]");
},
initialize: function() { initialize: function() {
$(".accept-all-cookies").on("click", function() { $(".accept-all-cookies").on("click", function() {
App.Cookies.saveCookie("cookies_consent", "all", 365); 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(); App.CookiesConsent.hide();
}); });
$(".accept-essential-cookies").on("click", function() { $(".accept-essential-cookies").on("click", function() {
App.Cookies.saveCookie("cookies_consent", "essential", 365); 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(); App.CookiesConsent.hide();
}); });
} }

View File

@@ -16,29 +16,39 @@
.buttons { .buttons {
border-top: 1px solid $medium-gray; border-top: 1px solid $medium-gray;
margin-top: $line-height;
padding-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) { @include breakpoint(small only) {
display: block; margin-bottom: $line-height / 3;
width: 100%;
} }
}
&.accept-all-cookies, &.save-cookies-preferences {
&.accept-essential-cookies { @include hollow-button;
@include regular-button;
margin-bottom: 0;
}
&.accept-all-cookies {
@include breakpoint(small only) {
margin-bottom: $line-height / 3;
}
}
} }
} }
.cookies-essentials { .save-preferences {
text-align: #{$global-right};
}
.cookies-essentials,
.cookies-vendors {
ul { ul {
list-style: none; list-style: none;
margin-#{$global-left}: 0; margin-#{$global-left}: 0;

View File

@@ -24,6 +24,8 @@
</ul> </ul>
</div> </div>
<%= render Layout::CookiesConsent::VendorsComponent.new %>
<div class="buttons"> <div class="buttons">
<% if vendors.any? %> <% if vendors.any? %>
<button type="button" class="accept-all-cookies"><%= t("cookies_consent.accept_all_cookies") %></button> <button type="button" class="accept-all-cookies"><%= t("cookies_consent.accept_all_cookies") %></button>

View File

@@ -0,0 +1,20 @@
<h3><%= t("cookies_management.third_party.title") %></h3>
<p><%= t("cookies_management.third_party.description") %></p>
<div class="cookies-vendors">
<ul>
<% vendors.each do |vendor| %>
<li id="<%= dom_id(vendor) %>">
<%= render Layout::CookiesConsent::SwitchComponent.new(vendor.cookie,
label: vendor.name,
description: vendor.description,
checked: enabled?(vendor),
disabled: false) %>
</li>
<% end %>
</ul>
<div class="save-preferences">
<button type="button" class="save-cookies-preferences"><%= t("cookies_management.save_preferences") %></button>
</div>
</div>

View File

@@ -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

View File

@@ -943,8 +943,12 @@ en:
title: "Cookies policy" title: "Cookies policy"
cookies_management: cookies_management:
title: 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: essentials:
title: Essential cookies 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. 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. 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

View File

@@ -943,8 +943,12 @@ es:
title: "Política de cookies" title: "Política de cookies"
cookies_management: cookies_management:
title: Configuración de cookies 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: essentials:
title: Cookies esenciales 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. 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. 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

View File

@@ -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_link "More information about cookies", href: "/cookies_policy"
expect(page).to have_css "h3", text: "Essential cookies" 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 ".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 all"
expect(page).to have_button "Accept essential cookies" expect(page).to have_button "Accept essential cookies"
end end

View File

@@ -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

View File

@@ -1,19 +1,24 @@
require "rails_helper" require "rails_helper"
describe "Cookies consent" do 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 context "Banner consent" do
scenario "Hides the banner when accepting essential cookies and for consecutive visits" do scenario "Hides the banner when accepting essential cookies and for consecutive visits" do
visit root_path visit root_path
expect(cookie_by_name("cookies_consent")).to be nil expect(cookie_by_name("cookies_consent")).to be nil
expect(cookie_by_name("third_party")).to be nil
within ".cookies-consent-banner" do within ".cookies-consent-banner" do
click_button "Accept essential cookies" click_button "Accept essential cookies"
end end
expect(cookie_by_name("cookies_consent")[:value]).to eq "essential" 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 policy"
refresh refresh
@@ -25,12 +30,14 @@ describe "Cookies consent" do
visit root_path visit root_path
expect(cookie_by_name("cookies_consent")).to be nil expect(cookie_by_name("cookies_consent")).to be nil
expect(cookie_by_name("third_party")).to be nil
within ".cookies-consent-banner" do within ".cookies-consent-banner" do
click_button "Accept all" click_button "Accept all"
end end
expect(cookie_by_name("cookies_consent")[:value]).to eq "all" 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 policy"
refresh refresh
@@ -44,6 +51,7 @@ describe "Cookies consent" do
visit root_path visit root_path
expect(cookie_by_name("cookies_consent")).to be nil expect(cookie_by_name("cookies_consent")).to be nil
expect(cookie_by_name("third_party")).to be nil
within ".cookies-consent-banner" do within ".cookies-consent-banner" do
click_button "Manage cookies" click_button "Manage cookies"
@@ -54,6 +62,7 @@ describe "Cookies consent" do
end end
expect(cookie_by_name("cookies_consent")[:value]).to eq "essential" 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 policy"
expect(page).not_to have_content "Cookies management" expect(page).not_to have_content "Cookies management"
@@ -66,6 +75,7 @@ describe "Cookies consent" do
visit root_path visit root_path
expect(cookie_by_name("cookies_consent")).to be nil expect(cookie_by_name("cookies_consent")).to be nil
expect(cookie_by_name("third_party")).to be nil
within ".cookies-consent-banner" do within ".cookies-consent-banner" do
click_button "Manage cookies" click_button "Manage cookies"
@@ -76,6 +86,35 @@ describe "Cookies consent" do
end end
expect(cookie_by_name("cookies_consent")[:value]).to eq "all" 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 policy"
expect(page).not_to have_content "Cookies management" expect(page).not_to have_content "Cookies management"