Merge pull request #4311 from consul/sdg_cards

Add SDG cards management section
This commit is contained in:
Javi Martín
2021-01-18 11:58:02 +01:00
committed by GitHub
57 changed files with 447 additions and 83 deletions

View File

@@ -31,4 +31,5 @@
@import "admin/*";
@import "sdg/**/*";
@import "sdg_management/*";
@import "sdg_management/**/*";
@import "widgets/**/*";

View File

@@ -91,12 +91,8 @@ a {
}
.button {
@extend %button;
background: $brand;
font-size: $base-font-size;
&:hover {
text-decoration: none !important;
}
&.warning,
&.warning:hover {

View File

@@ -199,17 +199,26 @@
}
}
@mixin hollow-button($color: $link) {
@include button($style: hollow, $background: $color);
%button {
font-size: $base-font-size;
margin-bottom: 0;
&:focus,
&:hover {
text-decoration: none;
text-decoration: none !important;
}
}
@mixin regular-button($color: $brand) {
@include button($background: $color);
@extend %button;
}
@mixin hollow-button($color: $link) {
@include button($style: hollow, $background: $color);
@extend %button;
margin-bottom: 0;
}
@mixin header-font-size($heading-tag) {
@each $size, $headers in $header-styles {
@include breakpoint($size) {

View File

@@ -0,0 +1,11 @@
.phase-cards {
> header {
align-items: flex-start;
display: flex;
a {
@include regular-button;
margin-left: auto;
}
}
}

View File

@@ -7,4 +7,12 @@
mask-image: image-url("sdg.svg");
}
.homepage-link {
@include has-fa-icon(home, solid);
&::before {
@extend %admin-menu-icon;
}
}
}

View File

@@ -1,6 +1,7 @@
class Admin::TableActionsComponent < ApplicationComponent
include TableActionLink
attr_reader :record, :options
delegate :namespace, to: :helpers
def initialize(record = nil, **options)
@record = record
@@ -18,7 +19,7 @@ class Admin::TableActionsComponent < ApplicationComponent
end
def edit_path
options[:edit_path] || admin_polymorphic_path(record, action: :edit)
options[:edit_path] || namespaced_polymorphic_path(namespace, record, action: :edit)
end
def edit_options
@@ -30,7 +31,7 @@ class Admin::TableActionsComponent < ApplicationComponent
end
def destroy_path
options[:destroy_path] || admin_polymorphic_path(record)
options[:destroy_path] || namespaced_polymorphic_path(namespace, record)
end
def destroy_options

View File

@@ -0,0 +1,3 @@
<%= back_link_to index_path %>
<%= header %>
<%= render "admin/widget/cards/form", card: card %>

View File

@@ -0,0 +1,19 @@
class Admin::Widget::Cards::EditComponent < ApplicationComponent
include Header
attr_reader :card, :index_path
def initialize(card, index_path:)
@card = card
@index_path = index_path
end
private
def title
if card.header?
t("admin.homepage.edit.header_title")
else
t("admin.homepage.edit.card_title")
end
end
end

View File

@@ -0,0 +1,3 @@
<%= back_link_to index_path %>
<%= header %>
<%= render "admin/widget/cards/form", card: card %>

View File

@@ -0,0 +1,19 @@
class Admin::Widget::Cards::NewComponent < ApplicationComponent
include Header
attr_reader :card, :index_path
def initialize(card, index_path:)
@card = card
@index_path = index_path
end
private
def title
if card.header?
t("admin.homepage.new.header_title")
else
t("admin.homepage.new.card_title")
end
end
end

View File

@@ -1,3 +1,4 @@
class ApplicationComponent < ViewComponent::Base
include SettingsHelper
delegate :back_link_to, to: :helpers
end

View File

@@ -1,6 +1,5 @@
class SDG::Goals::ShowComponent < ApplicationComponent
attr_reader :goal
delegate :back_link_to, to: :helpers
def initialize(goal)
@goal = goal

View File

@@ -0,0 +1,15 @@
<%= header %>
<% phases.each do |phase| %>
<section class="phase-cards <%= phase.kind %>-cards">
<header>
<h3><%= phase.title %></h3>
<%= link_to create_card_text(phase), new_sdg_management_sdg_phase_widget_card_path(phase) %>
</header>
<%= render Admin::Widget::Cards::TableComponent.new(
phase.cards,
no_cards_message: no_cards_message
) %>
</section>
<% end %>

View File

@@ -0,0 +1,23 @@
class SDGManagement::Homepage::ShowComponent < ApplicationComponent
include Header
attr_reader :phases
def initialize(phases)
@phases = phases
end
private
def title
t("sdg_management.homepage.title")
end
def create_card_text(phase)
t("sdg_management.homepage.create_card", phase: phase.title.downcase)
end
def no_cards_message
t("sdg_management.homepage.no_cards")
end
end

View File

@@ -1,5 +1,4 @@
class SDGManagement::LocalTargets::FormComponent < ApplicationComponent
delegate :back_link_to, to: :helpers
include Header
include TranslatableFormHelper
include GlobalizeHelper

View File

@@ -22,9 +22,6 @@ class SDGManagement::LocalTargets::IndexComponent < ApplicationComponent
end
def actions(local_target)
render Admin::TableActionsComponent.new(
local_target,
edit_path: edit_sdg_management_local_target_path(local_target),
destroy_path: sdg_management_local_target_path(local_target))
render Admin::TableActionsComponent.new(local_target)
end
end

View File

@@ -4,11 +4,15 @@ class SDGManagement::MenuComponent < ApplicationComponent
private
def links
[goals_link, *relatable_links]
[goals_link, homepage_link, *relatable_links]
end
def goals_link
[t("sdg_management.menu.sdg_content"), sdg_management_goals_path, sdg?, class: "goals-link"]
[item_text("sdg_content"), sdg_management_goals_path, sdg?, class: "goals-link"]
end
def homepage_link
[item_text("sdg_homepage"), sdg_management_homepage_path, homepage?, class: "homepage-link"]
end
def relatable_links
@@ -16,7 +20,7 @@ class SDGManagement::MenuComponent < ApplicationComponent
next unless SDG::ProcessEnabled.new(type).enabled?
[
t("sdg_management.menu.#{table_name(type)}"),
item_text(table_name(type)),
relatable_type_path(type),
controller_name == "relations" && params[:relatable_type] == type.tableize,
class: "#{table_name(type).tr("_", "-")}-link"
@@ -28,6 +32,10 @@ class SDGManagement::MenuComponent < ApplicationComponent
%w[goals targets local_targets].include?(controller_name)
end
def homepage?
controller_name == "homepage"
end
def relatable_type_path(type)
{
controller: "sdg_management/relations",
@@ -39,4 +47,8 @@ class SDGManagement::MenuComponent < ApplicationComponent
def table_name(type)
type.constantize.table_name
end
def item_text(item)
t("sdg_management.menu.#{item}")
end
end

View File

@@ -0,0 +1,13 @@
class SDGManagement::CardsController < SDGManagement::BaseController
include Admin::Widget::CardsActions
helper_method :index_path
load_and_authorize_resource :phase, class: "SDG::Phase", id_param: "sdg_phase_id"
load_and_authorize_resource :card, through: :phase, class: "Widget::Card"
private
def index_path
sdg_management_homepage_path
end
end

View File

@@ -0,0 +1,5 @@
class SDGManagement::HomepageController < SDGManagement::BaseController
def show
@phases = SDG::Phase.accessible_by(current_ability).order(:kind)
end
end

View File

@@ -39,9 +39,7 @@ module AdminHelper
user_roles(user).join(", ")
end
private
def namespace
controller.class.name.split("::").first.underscore
end
def namespace
controller.class.name.split("::").first.underscore
end
end

View File

@@ -29,6 +29,7 @@ module Abilities
can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation
can :read, ::SDG::Goal
can :read, ::SDG::Phase
end
end
end

View File

@@ -6,5 +6,7 @@ class Abilities::SDG::Manager
can :read, ::SDG::Target
can :manage, ::SDG::LocalTarget
can [:read, :update, :destroy], Widget::Card, cardable_type: "SDG::Phase"
can(:create, Widget::Card) { |card| card.cardable_type == "SDG::Phase" }
end
end

View File

@@ -0,0 +1,7 @@
module Cardable
extend ActiveSupport::Concern
included do
has_many :cards, class_name: "Widget::Card", as: :cardable, dependent: :destroy
end
end

13
app/models/sdg/phase.rb Normal file
View File

@@ -0,0 +1,13 @@
class SDG::Phase < ApplicationRecord
include Cardable
enum kind: %w[sensitization planning monitoring]
validates :kind, presence: true, uniqueness: true
def self.[](kind)
find_by!(kind: kind)
end
def title
self.class.human_attribute_name("kind.#{kind}")
end
end

View File

@@ -1,10 +1,6 @@
class SiteCustomization::Page < ApplicationRecord
VALID_STATUSES = %w[draft published].freeze
has_many :cards,
class_name: "Widget::Card",
foreign_key: "site_customization_page_id",
inverse_of: :page
include Cardable
translates :title, touch: true
translates :subtitle, touch: true
translates :content, touch: true

View File

@@ -1,9 +1,6 @@
class Widget::Card < ApplicationRecord
include Imageable
belongs_to :page,
class_name: "SiteCustomization::Page",
foreign_key: "site_customization_page_id",
inverse_of: :cards
belongs_to :cardable, polymorphic: true
translates :label, touch: true
translates :title, touch: true
@@ -18,6 +15,6 @@ class Widget::Card < ApplicationRecord
end
def self.body
where(header: false, site_customization_page_id: nil).order(:created_at)
where(header: false, cardable_id: nil).order(:created_at)
end
end

View File

@@ -1,7 +1,7 @@
<%= render "shared/globalize_locales", resource: @card %>
<%= render "shared/globalize_locales", resource: card %>
<%= translatable_form_for [:admin, @page, @card] do |f| %>
<%= render "shared/errors", resource: @card %>
<%= translatable_form_for [namespace, card.cardable, card] do |f| %>
<%= render "shared/errors", resource: card %>
<div class="row">
<%= f.translatable_fields do |translations_form| %>
@@ -30,7 +30,7 @@
</div>
<div class="row">
<% unless @card.header? %>
<% unless card.header? %>
<div class="column">
<%= f.label :columns %>
<p class="help-text"><%= t("admin.site_customization.pages.cards.columns_help") %></p>
@@ -41,16 +41,16 @@
<% end %>
</div>
<%= f.hidden_field :header, value: @card.header? %>
<%= f.hidden_field :header, value: card.header? %>
<div class="row">
<div class="image-form">
<div class="image small-12 column">
<%= render "images/nested_image", imageable: @card, f: f %>
<%= render "images/nested_image", imageable: card, f: f %>
</div>
</div>
<div class="column">
<%= f.submit(
t("admin.homepage.#{admin_submit_action(@card)}.#{@card.header? ? "submit_header" : "submit_card"}"),
t("admin.homepage.#{admin_submit_action(card)}.#{card.header? ? "submit_header" : "submit_card"}"),
class: "button success"
) %>
</div>

View File

@@ -1,11 +1 @@
<%= back_link_to index_path %>
<h2>
<% if @card.header? %>
<%= t("admin.homepage.edit.header_title") %>
<% else %>
<%= t("admin.homepage.edit.card_title") %>
<% end %>
</h2>
<%= render "admin/widget/cards/form" %>
<%= render Admin::Widget::Cards::EditComponent.new(@card, index_path: index_path) %>

View File

@@ -1,11 +1 @@
<%= back_link_to index_path %>
<h2>
<% if @card.header? %>
<%= t("admin.homepage.new.header_title") %>
<% else %>
<%= t("admin.homepage.new.card_title") %>
<% end %>
</h2>
<%= render "admin/widget/cards/form" %>
<%= render Admin::Widget::Cards::NewComponent.new(@card, index_path: index_path) %>

View File

@@ -0,0 +1 @@
<%= render SDGManagement::Homepage::ShowComponent.new(@phases) %>

View File

@@ -16,14 +16,23 @@ module ActionDispatch::Routing::UrlFor
end
def admin_polymorphic_path(resource, options = {})
namespaced_polymorphic_path(:admin, resource, options)
end
def sdg_management_polymorphic_path(resource, options = {})
namespaced_polymorphic_path(:sdg_management, resource, options)
end
def namespaced_polymorphic_path(namespace, resource, options = {})
if %w[Budget::Group Budget::Heading Poll::Booth Poll::BoothAssignment Poll::Officer
Poll::Question Poll::Question::Answer::Video Poll::Shift].include?(resource.class.name)
Poll::Question Poll::Question::Answer::Video Poll::Shift
SDG::LocalTarget].include?(resource.class.name)
resolve = resolve_for(resource)
resolve_options = resolve.pop
polymorphic_path([:admin, *resolve], options.merge(resolve_options))
polymorphic_path([namespace, *resolve], options.merge(resolve_options))
else
polymorphic_path([:admin, *resource_hierarchy_for(resource)], options)
polymorphic_path([namespace, *resource_hierarchy_for(resource)], options)
end
end

View File

@@ -336,6 +336,10 @@ en:
sdg/local_target/translation:
title: "Title"
description: "Description"
sdg/phase/kind:
sensitization: "Sensitization"
planning: "Planning"
monitoring: "Monitoring"
sdg/target:
code: "Code"
title: "Title"

View File

@@ -4,6 +4,10 @@ en:
edit: "Manage goals and targets"
header:
title: "SDG content"
homepage:
title: "Homepage configuration"
create_card: "Create %{phase} card"
no_cards: "There are no cards for this phase"
menu:
budget_investments: "Participatory budgets"
debates: "Debates"
@@ -11,6 +15,7 @@ en:
polls: "Polls"
proposals: "Proposals"
sdg_content: "Goals and Targets"
sdg_homepage: "SDG homepage"
local_targets:
create:
notice: "Local target created successfully"

View File

@@ -331,6 +331,10 @@ es:
sdg/local_target/translation:
title: "Título"
description: "Descripción"
sdg/phase/kind:
sensitization: "Sensibilización"
planning: "Planificación"
monitoring: "Seguimiento"
sdg/target:
code: "Código"
title: "Título"

View File

@@ -4,6 +4,10 @@ es:
edit: "Asignar objetivos y metas"
header:
title: "Contenido ODS"
homepage:
title: "Configuración de la página de inicio"
create_card: "Crear tarjeta de %{phase}"
no_cards: "No hay tarjetas para esta fase"
menu:
budget_investments: "Presupuestos participativos"
debates: "Debates"
@@ -11,6 +15,7 @@ es:
polls: "Votaciones"
proposals: "Propuestas"
sdg_content: "Objetivos y Metas"
sdg_homepage: "Página de inicio ODS"
local_targets:
create:
notice: "Meta localizada creada correctamente"

View File

@@ -271,7 +271,7 @@ resolve "Audit" do |audit|
end
resolve "Widget::Card" do |card, options|
[*resource_hierarchy_for(card.page), card]
[*resource_hierarchy_for(card.cardable), card]
end
resolve "Budget::Group" do |group, options|

View File

@@ -4,6 +4,11 @@ namespace :sdg_management do
resources :goals, only: [:index]
resources :targets, only: [:index]
resources :local_targets, except: [:show]
resource :homepage, controller: :homepage, only: [:show]
resources :phases, only: [], as: :sdg_phases do
resources :cards, except: [:index, :show], as: :widget_cards
end
types = SDG::Related::RELATABLE_TYPES.map(&:tableize)
types_constraint = /#{types.join("|")}/
@@ -17,3 +22,7 @@ namespace :sdg_management do
get "#{type}/:id/edit", to: "relations#edit", as: "edit_#{type.singularize}"
end
end
resolve "SDG::LocalTarget" do |target, options|
[:local_target, options.merge(id: target)]
end

View File

@@ -30,3 +30,9 @@ section "Creating Sustainable Development Goals" do
end
end
end
section "Creating SDG homepage cards" do
SDG::Phase.all.each do |phase|
Widget::Card.create!(cardable: phase, title: "#{phase.title} card")
end
end

View File

@@ -0,0 +1,8 @@
class MakeCardsPolymorphic < ActiveRecord::Migration[5.2]
def change
change_table :widget_cards do |t|
t.rename :site_customization_page_id, :cardable_id
t.string :cardable_type, default: "SiteCustomization::Page"
end
end
end

View File

@@ -0,0 +1,9 @@
class CreateSDGPhases < ActiveRecord::Migration[5.2]
def change
create_table :sdg_phases do |t|
t.integer :kind, null: false
t.index :kind, unique: true
t.timestamps
end
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_12_16_132642) do
ActiveRecord::Schema.define(version: 2021_01_07_125458) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -1333,6 +1333,13 @@ ActiveRecord::Schema.define(version: 2020_12_16_132642) do
t.index ["user_id"], name: "index_sdg_managers_on_user_id", unique: true
end
create_table "sdg_phases", force: :cascade do |t|
t.integer "kind", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["kind"], name: "index_sdg_phases_on_kind", unique: true
end
create_table "sdg_relations", force: :cascade do |t|
t.string "related_sdg_type"
t.bigint "related_sdg_id"
@@ -1647,9 +1654,10 @@ ActiveRecord::Schema.define(version: 2020_12_16_132642) do
t.boolean "header", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "site_customization_page_id"
t.integer "cardable_id"
t.integer "columns", default: 4
t.index ["site_customization_page_id"], name: "index_widget_cards_on_site_customization_page_id"
t.string "cardable_type", default: "SiteCustomization::Page"
t.index ["cardable_id"], name: "index_widget_cards_on_cardable_id"
end
create_table "widget_feeds", id: :serial, force: :cascade do |t|

View File

@@ -23,3 +23,5 @@ end
].each do |code|
SDG::Target.where(code: code, goal: SDG::Goal.find_by!(code: code.split(".").first)).first_or_create!
end
SDG::Phase.kinds.values.each { |kind| SDG::Phase.where(kind: kind).first_or_create! }

View File

@@ -4,6 +4,10 @@ describe Admin::Budgets::TableActionsComponent, type: :component do
let(:budget) { create(:budget) }
let(:component) { Admin::Budgets::TableActionsComponent.new(budget) }
before do
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
end
it "renders links to edit budget, manage investments and edit groups and manage ballots" do
render_inline component

View File

@@ -6,6 +6,10 @@ describe Admin::Poll::Officers::OfficersComponent, type: :component do
let(:officers) { [existing_officer, new_officer] }
let(:component) { Admin::Poll::Officers::OfficersComponent.new(officers) }
before do
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
end
it "renders as many rows as officers" do
render_inline component

View File

@@ -3,6 +3,10 @@ require "rails_helper"
describe Admin::Roles::TableActionsComponent, type: :component do
let(:user) { create(:user) }
before do
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
end
it "renders link to add the role for new records" do
render_inline Admin::Roles::TableActionsComponent.new(user.build_manager)

View File

@@ -3,6 +3,10 @@ require "rails_helper"
describe Admin::TableActionsComponent, type: :component do
let(:record) { create(:banner) }
before do
allow(ViewComponent::Base).to receive(:test_controller).and_return("Admin::BaseController")
end
it "renders links to edit and destroy a record by default" do
render_inline Admin::TableActionsComponent.new(record)
@@ -65,4 +69,18 @@ describe Admin::TableActionsComponent, type: :component do
expect(page).to have_link "Edit"
expect(page).to have_link "Delete"
end
context "different namespace" do
before do
allow(ViewComponent::Base).to receive(:test_controller).and_return("SDGManagement::BaseController")
end
it "generates links to different namespaces" do
render_inline Admin::TableActionsComponent.new(create(:sdg_local_target))
expect(page).to have_css "a", count: 2
expect(page).to have_css "a[href^='/sdg_management/'][href*='edit']", text: "Edit"
expect(page).to have_css "a[href^='/sdg_management/'][data-method='delete']", text: "Delete"
end
end
end

View File

@@ -17,6 +17,7 @@ describe SDGManagement::MenuComponent, type: :component do
render_inline component
expect(page).to have_link "Goals and Targets"
expect(page).to have_link "SDG homepage"
expect(page).to have_link "Participatory budgets"
expect(page).to have_link "Debates"
expect(page).to have_link "Collaborative legislation"
@@ -37,8 +38,9 @@ describe SDGManagement::MenuComponent, type: :component do
it "does not generate links to any processes" do
render_inline component
expect(page).to have_css "a", count: 1
expect(page).to have_css "a", count: 2
expect(page).to have_link "Goals and Targets"
expect(page).to have_link "SDG homepage"
end
end
@@ -54,8 +56,9 @@ describe SDGManagement::MenuComponent, type: :component do
it "does not generate links to any processes" do
render_inline component
expect(page).to have_css "a", count: 1
expect(page).to have_css "a", count: 2
expect(page).to have_link "Goals and Targets"
expect(page).to have_link "SDG homepage"
end
end
@@ -66,6 +69,7 @@ describe SDGManagement::MenuComponent, type: :component do
render_inline component
expect(page).to have_link "Goals and Targets"
expect(page).to have_link "SDG homepage"
expect(page).to have_link "Participatory budgets"
expect(page).to have_link "Collaborative legislation"
expect(page).to have_link "Polls"
@@ -82,6 +86,7 @@ describe SDGManagement::MenuComponent, type: :component do
render_inline component
expect(page).to have_link "Goals and Targets"
expect(page).to have_link "SDG homepage"
expect(page).to have_link "Debates"
expect(page).to have_link "Participatory budgets"
expect(page).to have_link "Polls"

View File

@@ -14,4 +14,8 @@ FactoryBot.define do
target { SDG::Target[code.rpartition(".").first] }
end
factory :sdg_phase, class: "SDG::Phase" do
kind { :sensitization }
end
end

View File

@@ -9,27 +9,33 @@ describe "rake db:load_sdg" do
it "populates empty databases and assigns targets correctly" do
SDG::Goal.destroy_all
SDG::Phase.destroy_all
run_rake_task
expect(SDG::Goal.count).to eq 17
expect(SDG::Target.count).to eq 169
expect(SDG::Target["17.1"].goal.code).to eq 17
expect(SDG::Phase.count).to eq 3
end
it "does not create additional records on populated databases" do
expect(SDG::Goal.count).to eq 17
expect(SDG::Target.count).to eq 169
expect(SDG::Phase.count).to eq 3
goal_id = SDG::Goal.last.id
target_id = SDG::Target.last.id
phase_id = SDG::Phase.last.id
run_rake_task
expect(SDG::Goal.count).to eq 17
expect(SDG::Target.count).to eq 169
expect(SDG::Phase.count).to eq 3
expect(SDG::Goal.last.id).to eq goal_id
expect(SDG::Target.last.id).to eq target_id
expect(SDG::Phase.last.id).to eq phase_id
end
end

View File

@@ -55,6 +55,7 @@ describe Abilities::Everyone do
it { should be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should be_able_to(:read, SDG::Phase) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }

View File

@@ -13,4 +13,9 @@ describe "Abilities::SDG::Manager" 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(:update, create(:widget_card)) }
it { should be_able_to(:update, create(:widget_card, cardable: SDG::Phase.sample)) }
it { should_not be_able_to(:create, build(:widget_card)) }
it { should be_able_to(:create, build(:widget_card, cardable: SDG::Phase.sample)) }
end

View File

@@ -0,0 +1,44 @@
require "rails_helper"
describe SDG::Phase do
let(:phase) { build(:sdg_phase) }
before { SDG::Phase["sensitization"].destroy }
it "is valid with a valid kind" do
phase.kind = "sensitization"
expect(phase).to be_valid
end
it "is not valid without a kind" do
phase.kind = nil
expect(phase).not_to be_valid
end
it "is not valid with a duplicate kind" do
phase.kind = "planning"
expect(phase).not_to be_valid
end
it "is not valid with a custom kind" do
expect { phase.kind = "improvement" }.to raise_exception(ArgumentError)
end
describe ".[]" do
it "finds existing phases by kind" do
expect(SDG::Phase["monitoring"].kind).to eq "monitoring"
end
it "raises an exception on empty databases" do
SDG::Phase["monitoring"].destroy!
expect { SDG::Phase["monitoring"] }.to raise_exception ActiveRecord::RecordNotFound
end
it "raises an exception for non-existing kinds" do
expect { SDG::Phase["improvement"] }.to raise_exception ActiveRecord::StatementInvalid
end
end
end

View File

@@ -34,7 +34,7 @@ describe Widget::Card do
header = create(:widget_card, header: true)
card1 = create(:widget_card, header: false)
card2 = create(:widget_card, header: false)
page_card = create(:widget_card, header: false, page: create(:site_customization_page))
page_card = create(:widget_card, header: false, cardable: create(:site_customization_page))
expect(Widget::Card.body).to match_array [card1, card2]
expect(Widget::Card.body).not_to include(header)

View File

@@ -172,7 +172,7 @@ describe "Polymorphic routes" do
it "routes site customization page widget cards" do
page = create(:site_customization_page)
card = create(:widget_card, page: page)
card = create(:widget_card, cardable: page)
expect(admin_polymorphic_path(card)).to eq admin_site_customization_page_widget_card_path(page, card)
end
@@ -186,6 +186,25 @@ describe "Polymorphic routes" do
)
end
end
describe "sdg_management_polymorphic_path" do
include ActionDispatch::Routing::UrlFor
it "routes local targets" do
target = create(:sdg_local_target)
expect(sdg_management_polymorphic_path(target)).to eq sdg_management_local_target_path(target)
end
it "routes SDG phases widget cards" do
phase = SDG::Phase.sample
card = create(:widget_card, cardable: phase)
expect(sdg_management_polymorphic_path(card)).to eq(
sdg_management_sdg_phase_widget_card_path(phase, card)
)
end
end
end
def polymorphic_path(record, options = {})

View File

@@ -175,9 +175,9 @@ describe "Cards", :admin do
end
scenario "Show" do
card_1 = create(:widget_card, page: custom_page, title: "Card large", columns: 8)
card_2 = create(:widget_card, page: custom_page, title: "Card medium", columns: 4)
card_3 = create(:widget_card, page: custom_page, title: "Card small", columns: 2)
card_1 = create(:widget_card, cardable: custom_page, title: "Card large", columns: 8)
card_2 = create(:widget_card, cardable: custom_page, title: "Card medium", columns: 4)
card_3 = create(:widget_card, cardable: custom_page, title: "Card small", columns: 2)
visit custom_page.url
@@ -189,8 +189,8 @@ describe "Cards", :admin do
end
scenario "Show label only if it is present" do
card_1 = create(:widget_card, page: custom_page, title: "Card one", label: "My label")
card_2 = create(:widget_card, page: custom_page, title: "Card two")
card_1 = create(:widget_card, cardable: custom_page, title: "Card one", label: "My label")
card_2 = create(:widget_card, cardable: custom_page, title: "Card two")
visit custom_page.url
@@ -204,7 +204,7 @@ describe "Cards", :admin do
end
scenario "Edit", :js do
create(:widget_card, page: custom_page, title: "Original title")
create(:widget_card, cardable: custom_page, title: "Original title")
visit admin_site_customization_page_widget_cards_path(custom_page)
@@ -227,7 +227,7 @@ describe "Cards", :admin do
end
scenario "Destroy", :js do
create(:widget_card, page: custom_page, title: "Card title")
create(:widget_card, cardable: custom_page, title: "Card title")
visit admin_site_customization_page_widget_cards_path(custom_page)

View File

@@ -0,0 +1,52 @@
require "rails_helper"
describe "SDG homepage configuration", :js do
before do
Setting["feature.sdg"] = true
login_as(create(:sdg_manager).user)
end
describe "Show" do
scenario "Visit the index" do
visit sdg_management_root_path
within("#side_menu") do
click_link "SDG homepage"
end
expect(page).to have_title "SDG content - Homepage configuration"
end
scenario "Create card" do
visit sdg_management_homepage_path
click_link "Create planning card"
within(".translatable-fields") { fill_in "Title", with: "My planning card" }
click_button "Create card"
within(".planning-cards") do
expect(page).to have_content "My planning card"
end
within(".sensitization-cards") do
expect(page).to have_content "There are no cards for this phase"
end
end
scenario "Update card" do
create(:widget_card, cardable: SDG::Phase["monitoring"], title: "My monitoring card")
visit sdg_management_homepage_path
within(".monitoring-cards") { click_link "Edit" }
within(".translatable-fields") { fill_in "Title", with: "Updated monitoring card" }
click_button "Save card"
within(".monitoring-cards") do
expect(page).to have_css "tbody tr", count: 1
expect(page).to have_content "Updated monitoring card"
expect(page).not_to have_content "My monitoring card"
end
end
end
end

View File

@@ -104,7 +104,7 @@ describe "Custom Pages" do
scenario "Show widget cards for that page" do
custom_page = create(:site_customization_page, :published)
create(:widget_card, page: custom_page, title: "Card Highlights")
create(:widget_card, cardable: custom_page, title: "Card Highlights")
visit custom_page.url