Allow administrators to define the cookies vendors the application uses
This commit is contained in:
5
app/components/admin/cookies/vendors/edit_component.html.erb
vendored
Normal file
5
app/components/admin/cookies/vendors/edit_component.html.erb
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<%= back_link_to admin_settings_path(anchor: "tab-cookies-consent") %>
|
||||
|
||||
<%= header %>
|
||||
|
||||
<%= render Admin::Cookies::Vendors::FormComponent.new(vendor) %>
|
||||
15
app/components/admin/cookies/vendors/edit_component.rb
vendored
Normal file
15
app/components/admin/cookies/vendors/edit_component.rb
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
class Admin::Cookies::Vendors::EditComponent < ApplicationComponent
|
||||
include Header
|
||||
|
||||
attr_reader :vendor
|
||||
|
||||
def initialize(vendor)
|
||||
@vendor = vendor
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def title
|
||||
t("admin.cookies.vendors.edit.title")
|
||||
end
|
||||
end
|
||||
10
app/components/admin/cookies/vendors/form_component.html.erb
vendored
Normal file
10
app/components/admin/cookies/vendors/form_component.html.erb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<%= form_for [:admin, vendor], html: { class: "vendor-form" } do |f| %>
|
||||
<%= render "shared/errors", resource: vendor %>
|
||||
|
||||
<%= f.text_field :name, hint: t("admin.cookies.vendors.form.name.help_text") %>
|
||||
<%= f.text_area :description, hint: t("admin.cookies.vendors.form.description.help_text"), rows: 4 %>
|
||||
<%= f.text_field :cookie, hint: t("admin.cookies.vendors.form.cookie.help_text") %>
|
||||
<%= f.text_area :script, hint: t("admin.cookies.vendors.form.script.help_text"), rows: 10 %>
|
||||
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
7
app/components/admin/cookies/vendors/form_component.rb
vendored
Normal file
7
app/components/admin/cookies/vendors/form_component.rb
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
class Admin::Cookies::Vendors::FormComponent < ApplicationComponent
|
||||
attr_reader :vendor
|
||||
|
||||
def initialize(vendor)
|
||||
@vendor = vendor
|
||||
end
|
||||
end
|
||||
5
app/components/admin/cookies/vendors/new_component.html.erb
vendored
Normal file
5
app/components/admin/cookies/vendors/new_component.html.erb
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<%= back_link_to admin_settings_path(anchor: "tab-cookies-consent") %>
|
||||
|
||||
<%= header %>
|
||||
|
||||
<%= render Admin::Cookies::Vendors::FormComponent.new(vendor) %>
|
||||
15
app/components/admin/cookies/vendors/new_component.rb
vendored
Normal file
15
app/components/admin/cookies/vendors/new_component.rb
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
class Admin::Cookies::Vendors::NewComponent < ApplicationComponent
|
||||
include Header
|
||||
|
||||
attr_reader :vendor
|
||||
|
||||
def initialize(vendor)
|
||||
@vendor = vendor
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def title
|
||||
t("admin.cookies.vendors.new.title")
|
||||
end
|
||||
end
|
||||
5
app/components/admin/cookies/vendors/row_component.html.erb
vendored
Normal file
5
app/components/admin/cookies/vendors/row_component.html.erb
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<tr id="<%= dom_id(vendor) %>" class="vendor">
|
||||
<td><%= vendor.name %></td>
|
||||
<td><%= vendor.cookie %></td>
|
||||
<td><%= render Admin::TableActionsComponent.new(vendor) %></td>
|
||||
</tr>
|
||||
9
app/components/admin/cookies/vendors/row_component.rb
vendored
Normal file
9
app/components/admin/cookies/vendors/row_component.rb
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class Admin::Cookies::Vendors::RowComponent < ApplicationComponent
|
||||
with_collection_parameter :vendor
|
||||
|
||||
attr_reader :vendor
|
||||
|
||||
def initialize(vendor:)
|
||||
@vendor = vendor
|
||||
end
|
||||
end
|
||||
22
app/components/admin/cookies/vendors/table_component.html.erb
vendored
Normal file
22
app/components/admin/cookies/vendors/table_component.html.erb
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<h3><%= t("admin.cookies.vendors.third_party_cookies") %></h3>
|
||||
|
||||
<% if vendors.any? %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= attribute_name(:name) %></th>
|
||||
<th><%= attribute_name(:cookie) %></th>
|
||||
<th><%= t("admin.shared.actions") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%= render Admin::Cookies::Vendors::RowComponent.with_collection(vendors) %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% else %>
|
||||
<div class="callout primary clear">
|
||||
<%= t("admin.cookies.vendors.empty") %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= link_to t("admin.cookies.vendors.create_button"), new_admin_cookies_vendor_path, class: "button" %>
|
||||
11
app/components/admin/cookies/vendors/table_component.rb
vendored
Normal file
11
app/components/admin/cookies/vendors/table_component.rb
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
class Admin::Cookies::Vendors::TableComponent < ApplicationComponent
|
||||
private
|
||||
|
||||
def vendors
|
||||
::Cookies::Vendor.all
|
||||
end
|
||||
|
||||
def attribute_name(attribute)
|
||||
::Cookies::Vendor.human_attribute_name(attribute)
|
||||
end
|
||||
end
|
||||
@@ -4,3 +4,5 @@
|
||||
<%= render Admin::Settings::RowComponent.new("feature.cookies_consent", type: :feature, tab: tab) %>
|
||||
<%= render Admin::Settings::RowComponent.new("cookies_consent.more_info_link", type: :text, tab: tab) %>
|
||||
<% end %>
|
||||
|
||||
<%= render Admin::Cookies::Vendors::TableComponent.new %>
|
||||
|
||||
38
app/controllers/admin/cookies/vendors_controller.rb
Normal file
38
app/controllers/admin/cookies/vendors_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class Admin::Cookies::VendorsController < Admin::BaseController
|
||||
load_and_authorize_resource :vendor, class: "::Cookies::Vendor"
|
||||
|
||||
def create
|
||||
if @vendor.save
|
||||
redirect_to admin_settings_path(anchor: "tab-cookies-consent"),
|
||||
notice: t("admin.cookies.vendors.create.notice")
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @vendor.update(vendor_params)
|
||||
redirect_to admin_settings_path(anchor: "tab-cookies-consent"),
|
||||
notice: t("admin.cookies.vendors.update.notice")
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@vendor.destroy!
|
||||
|
||||
redirect_to admin_settings_path(anchor: "tab-cookies-consent"),
|
||||
notice: t("admin.cookies.vendors.destroy.notice")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def vendor_params
|
||||
params.require(:cookies_vendor).permit(allowed_params)
|
||||
end
|
||||
|
||||
def allowed_params
|
||||
[:name, :description, :cookie, :script]
|
||||
end
|
||||
end
|
||||
@@ -142,6 +142,8 @@ module Abilities
|
||||
can :manage, LocalCensusRecord
|
||||
can [:create, :read], LocalCensusRecords::Import
|
||||
|
||||
can :manage, Cookies::Vendor
|
||||
|
||||
if Rails.application.config.multitenancy && Tenant.default?
|
||||
can [:create, :read, :update, :hide, :restore], Tenant
|
||||
end
|
||||
|
||||
5
app/models/cookies.rb
Normal file
5
app/models/cookies.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
module Cookies
|
||||
def self.table_name_prefix
|
||||
"cookies_"
|
||||
end
|
||||
end
|
||||
4
app/models/cookies/vendor.rb
Normal file
4
app/models/cookies/vendor.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class Cookies::Vendor < ApplicationRecord
|
||||
validates :name, presence: true
|
||||
validates :cookie, presence: true, uniqueness: true, format: { with: /\A[a-zA-Z0-9\_]+\Z/ }
|
||||
end
|
||||
1
app/views/admin/cookies/vendors/edit.html.erb
vendored
Normal file
1
app/views/admin/cookies/vendors/edit.html.erb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<%= render Admin::Cookies::Vendors::EditComponent.new(@vendor) %>
|
||||
1
app/views/admin/cookies/vendors/new.html.erb
vendored
Normal file
1
app/views/admin/cookies/vendors/new.html.erb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<%= render Admin::Cookies::Vendors::NewComponent.new(@vendor) %>
|
||||
@@ -151,6 +151,9 @@ en:
|
||||
votation_type:
|
||||
one: Votation type
|
||||
other: Votation types
|
||||
cookies/vendor:
|
||||
one: cookie vendor
|
||||
other: cookie vendors
|
||||
attributes:
|
||||
budget:
|
||||
name: "Name"
|
||||
@@ -534,6 +537,10 @@ en:
|
||||
votation_type/vote_type:
|
||||
unique: Unique answer
|
||||
multiple: Multiple answers
|
||||
cookies/vendor:
|
||||
name: Vendor name
|
||||
cookie: Cookie name
|
||||
script: Javascript code
|
||||
errors:
|
||||
models:
|
||||
user:
|
||||
|
||||
@@ -1808,3 +1808,27 @@ en:
|
||||
tags: "Tags"
|
||||
tags_description: "Generates automatic tags on all items that can be tagged on."
|
||||
title: "AI / Machine learning"
|
||||
cookies:
|
||||
vendors:
|
||||
empty: No vendors found
|
||||
third_party_cookies: Third party cookies
|
||||
create_button: Create cookie vendor
|
||||
create:
|
||||
notice: Cookie vendor created successfully
|
||||
new:
|
||||
title: New cookie vendor
|
||||
edit:
|
||||
title: Edit cookie vendor
|
||||
update:
|
||||
notice: Cookie vendor updated successfully
|
||||
destroy:
|
||||
notice: Cookie vendor deleted successfully
|
||||
form:
|
||||
name:
|
||||
help_text: This information will be publicly visible.
|
||||
cookie:
|
||||
help_text: This information will be used internally. The cookie name must be unique, and it can only contain letters, digits and underscores.
|
||||
description:
|
||||
help_text: This information will be publicly visible.
|
||||
script:
|
||||
help_text: This is the script to run when this cookie is accepted by the user. You can enter vanilla Javascript code here and introduce references to other application javascript.
|
||||
|
||||
@@ -151,6 +151,9 @@ es:
|
||||
votation_type:
|
||||
one: Tipo de votación
|
||||
other: Tipos de votación
|
||||
cookies/vendor:
|
||||
one: proveedor de cookies
|
||||
other: proveedores de cookies
|
||||
attributes:
|
||||
budget:
|
||||
name: "Nombre"
|
||||
@@ -534,6 +537,10 @@ es:
|
||||
votation_type/vote_type:
|
||||
unique: Respuesta única
|
||||
multiple: Respuesta múltiple
|
||||
cookies/vendor:
|
||||
name: Nombre del proveedor
|
||||
cookie: Nombre de la cookie
|
||||
script: Código javascript
|
||||
errors:
|
||||
models:
|
||||
user:
|
||||
|
||||
@@ -1808,3 +1808,27 @@ es:
|
||||
tags: "Etiquetas"
|
||||
tags_description: "Genera etiquetas automáticas para todos los elementos que pueden ser etiquetados."
|
||||
title: "IA / Machine learning"
|
||||
cookies:
|
||||
vendors:
|
||||
empty: No se han encontrado cookies de terceros
|
||||
third_party_cookies: Cookies de terceros
|
||||
create_button: Nueva cookie
|
||||
create:
|
||||
notice: Cookie creada correctamente
|
||||
new:
|
||||
title: Nueva cookie
|
||||
edit:
|
||||
title: Editar cookie
|
||||
update:
|
||||
notice: Cookie actualizada correctamente
|
||||
destroy:
|
||||
notice: Cookie eliminada correctamente
|
||||
form:
|
||||
name:
|
||||
help_text: Esta información será visible públicamente.
|
||||
cookie:
|
||||
help_text: Esta información se utilizará internamente. El nombre de la cookie debe ser único, solo puede contener letras, dígitos y guiones bajos.
|
||||
description:
|
||||
help_text: Esta información será visible públicamente.
|
||||
script:
|
||||
help_text: Este es el script que se ejecutará cuando esta cookie sea aceptada por el usuario. Puede introducir código Javascript aquí e introducir referencias a otro javascript de la aplicación.
|
||||
|
||||
@@ -304,6 +304,10 @@ namespace :admin do
|
||||
post :execute, on: :collection
|
||||
delete :cancel, on: :collection
|
||||
end
|
||||
|
||||
namespace :cookies do
|
||||
resources :vendors, except: [:index, :show]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
14
db/migrate/20240108110154_create_cookies_vendors.rb
Normal file
14
db/migrate/20240108110154_create_cookies_vendors.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateCookiesVendors < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :cookies_vendors do |t|
|
||||
t.string :name
|
||||
t.text :description
|
||||
t.string :cookie
|
||||
t.text :script
|
||||
|
||||
t.timestamps
|
||||
|
||||
t.index :cookie, unique: true
|
||||
end
|
||||
end
|
||||
end
|
||||
10
db/schema.rb
10
db/schema.rb
@@ -454,6 +454,16 @@ ActiveRecord::Schema[7.0].define(version: 2024_10_26_112901) do
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
end
|
||||
|
||||
create_table "cookies_vendors", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.text "description"
|
||||
t.string "cookie"
|
||||
t.text "script"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["cookie"], name: "index_cookies_vendors_on_cookie", unique: true
|
||||
end
|
||||
|
||||
create_table "dashboard_actions", id: :serial, force: :cascade do |t|
|
||||
t.string "title", limit: 80
|
||||
t.text "description"
|
||||
|
||||
7
spec/factories/cookies.rb
Normal file
7
spec/factories/cookies.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
FactoryBot.define do
|
||||
factory :cookies_vendor, class: "Cookies::Vendor" do
|
||||
name { "Vendor name" }
|
||||
sequence(:cookie) { |n| "vendor_cookie_#{n}" }
|
||||
description { "Vendor description" }
|
||||
end
|
||||
end
|
||||
@@ -172,6 +172,10 @@ describe Abilities::Administrator do
|
||||
|
||||
it { should be_able_to(:manage, Widget::Card) }
|
||||
|
||||
it { should be_able_to(:create, Cookies::Vendor) }
|
||||
it { should be_able_to(:update, Cookies::Vendor) }
|
||||
it { should be_able_to(:destroy, Cookies::Vendor) }
|
||||
|
||||
describe "tenants" do
|
||||
context "with multitenancy disabled" do
|
||||
before { allow(Rails.application.config).to receive(:multitenancy).and_return(false) }
|
||||
|
||||
@@ -372,4 +372,8 @@ describe Abilities::Common do
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
it { should_not be_able_to(:create, SDG::Manager) }
|
||||
it { should_not be_able_to(:delete, SDG::Manager) }
|
||||
|
||||
it { should_not be_able_to(:create, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:update, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:destroy, Cookies::Vendor) }
|
||||
end
|
||||
|
||||
@@ -113,4 +113,8 @@ describe Abilities::Moderator do
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
it { should_not be_able_to(:create, SDG::Manager) }
|
||||
it { should_not be_able_to(:delete, SDG::Manager) }
|
||||
|
||||
it { should_not be_able_to(:create, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:update, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:destroy, Cookies::Vendor) }
|
||||
end
|
||||
|
||||
@@ -51,4 +51,8 @@ describe Abilities::Valuator do
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
it { should_not be_able_to(:create, SDG::Manager) }
|
||||
it { should_not be_able_to(:delete, SDG::Manager) }
|
||||
|
||||
it { should_not be_able_to(:create, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:update, Cookies::Vendor) }
|
||||
it { should_not be_able_to(:destroy, Cookies::Vendor) }
|
||||
end
|
||||
|
||||
43
spec/models/cookies/vendor_spec.rb
Normal file
43
spec/models/cookies/vendor_spec.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Cookies::Vendor do
|
||||
let(:cookies_vendor) { build(:cookies_vendor) }
|
||||
|
||||
it "is valid" do
|
||||
expect(cookies_vendor).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without a name" do
|
||||
cookies_vendor.name = nil
|
||||
|
||||
expect(cookies_vendor).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid without the cookie name" do
|
||||
cookies_vendor.cookie = nil
|
||||
|
||||
expect(cookies_vendor).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid when cookie_name contains whitespaces, special characters" do
|
||||
cookies_vendor.cookie = "cookie vendor name"
|
||||
|
||||
expect(cookies_vendor).not_to be_valid
|
||||
|
||||
cookies_vendor.cookie = "cookie_vendor/name"
|
||||
|
||||
expect(cookies_vendor).not_to be_valid
|
||||
|
||||
cookies_vendor.cookie = "cookie_vendor_name"
|
||||
|
||||
expect(cookies_vendor).to be_valid
|
||||
end
|
||||
|
||||
it "is not valid when the cookie name already exists" do
|
||||
create(:cookies_vendor, cookie: "existing_name")
|
||||
|
||||
cookies_vendor.cookie = "existing_name"
|
||||
|
||||
expect(cookies_vendor).not_to be_valid
|
||||
end
|
||||
end
|
||||
62
spec/system/admin/cookies/vendors_spec.rb
Normal file
62
spec/system/admin/cookies/vendors_spec.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "Admin cookies vendors", :admin do
|
||||
describe "Index" do
|
||||
scenario "Shows existing cookies and links to actions" do
|
||||
create(:cookies_vendor, name: "Third party", cookie: "third_party")
|
||||
visit admin_settings_path(anchor: "tab-cookies-consent")
|
||||
|
||||
expect(page).to have_content "Third party"
|
||||
expect(page).to have_content "third_party"
|
||||
expect(page).to have_link "Edit"
|
||||
expect(page).to have_button "Delete"
|
||||
expect(page).to have_link "Create cookie vendor"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Create" do
|
||||
scenario "Shows a notice and the new cookie after creation" do
|
||||
visit admin_settings_path(anchor: "tab-cookies-consent")
|
||||
|
||||
click_link "Create cookie vendor"
|
||||
fill_in "Vendor name", with: "Vendor name"
|
||||
fill_in "Cookie name", with: "vendor_cookie"
|
||||
fill_in "Description", with: "Cookie details"
|
||||
click_button "Create cookie vendor"
|
||||
|
||||
expect(page).to have_content "Cookie vendor created successfully"
|
||||
expect(page).to have_content "Vendor name"
|
||||
expect(page).to have_content "vendor_cookie"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Update" do
|
||||
scenario "Shows a notice and the cookie changes after update" do
|
||||
create(:cookies_vendor, name: "Third party", cookie: "third_party")
|
||||
visit admin_settings_path(anchor: "tab-cookies-consent")
|
||||
|
||||
click_link "Edit"
|
||||
fill_in "Vendor name", with: "Cool Company Name"
|
||||
click_button "Update cookie vendor"
|
||||
|
||||
expect(page).to have_content "Cookie vendor updated successfully"
|
||||
expect(page).to have_content "Cool Company Name"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Destroy" do
|
||||
scenario "Shows a notice and removes cookie" do
|
||||
create(:cookies_vendor, name: "Analitics cookie", cookie: "analitics_cookie")
|
||||
visit admin_settings_path(anchor: "tab-cookies-consent")
|
||||
|
||||
expect(page).to have_content "Analitics cookie"
|
||||
expect(page).to have_content "analitics_cookie"
|
||||
|
||||
accept_confirm { click_button "Delete Analitics cookie" }
|
||||
|
||||
expect(page).to have_content "Cookie vendor deleted successfully"
|
||||
expect(page).not_to have_content "Analitics cookie"
|
||||
expect(page).not_to have_content "analitics_cookie"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user