diff --git a/Gemfile.lock b/Gemfile.lock index 73618cc..c0e1aae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,9 +88,9 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) - base64 (0.1.1) + base64 (0.2.0) batch-loader (1.5.0) - bcrypt (3.1.19) + bcrypt (3.1.20) better_html (1.0.16) actionview (>= 4.0) activesupport (>= 4.0) @@ -114,7 +114,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - carrierwave (2.2.4) + carrierwave (2.2.5) activemodel (>= 5.0.0) activesupport (>= 5.0.0) addressable (~> 2.6) @@ -155,7 +155,7 @@ GEM crass (1.0.6) css_parser (1.16.0) addressable - date (3.3.3) + date (3.3.4) date_validator (0.12.0) activemodel (>= 3) activesupport (>= 3) @@ -357,7 +357,7 @@ GEM nokogiri (>= 1.13.2, < 1.15.0) rubyzip (~> 2.3.0) docile (1.4.0) - doorkeeper (5.6.6) + doorkeeper (5.6.8) railties (>= 5) doorkeeper-i18n (4.0.1) dumb_delegator (1.0.0) @@ -373,7 +373,7 @@ GEM temple erubi (1.12.0) escape_utils (1.3.0) - excon (0.104.0) + excon (0.105.0) execjs (2.9.1) extended-markdown-filter (0.7.0) html-pipeline (~> 2.9) @@ -384,7 +384,7 @@ GEM railties (>= 3.0.0) faker (2.23.0) i18n (>= 1.8.11, < 2) - faraday (2.7.11) + faraday (2.7.12) base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) @@ -440,7 +440,7 @@ GEM rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) - icalendar (2.10.0) + icalendar (2.10.1) ice_cube (~> 0.16) ice_cube (0.16.4) ice_nine (0.11.2) @@ -449,7 +449,7 @@ GEM ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) - json (2.6.3) + json (2.7.1) jwt (2.7.1) kaminari (1.2.2) activesupport (>= 4.1.0) @@ -497,7 +497,7 @@ GEM method_source (1.0.0) mime-types (3.5.1) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1003) + mime-types-data (3.2023.1205) mini_magick (4.12.0) mini_mime (1.1.5) minitest (5.20.0) @@ -509,16 +509,16 @@ GEM msgpack (1.7.2) multi_xml (0.6.0) mustache (1.1.1) - net-imap (0.4.4) + net-imap (0.4.7) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout net-smtp (0.4.0) net-protocol - nio4r (2.5.9) + nio4r (2.7.0) nokogiri (1.14.5-x86_64-linux) racc (~> 1.4) oauth (1.1.0) @@ -580,10 +580,10 @@ GEM actionmailer (>= 3) net-smtp premailer (~> 1.7, >= 1.7.9) - public_suffix (5.0.3) + public_suffix (5.0.4) puma (5.6.7) nio4r (~> 2.0) - racc (1.7.2) + racc (1.7.3) rack (2.2.8) rack-attack (6.7.0) rack (>= 1.0, < 4) @@ -640,7 +640,7 @@ GEM ffi (~> 1.0) redcarpet (3.6.0) redis (4.8.1) - regexp_parser (2.8.2) + regexp_parser (2.8.3) request_store (1.5.1) rack (>= 1.4) responders (3.1.1) @@ -752,7 +752,7 @@ GEM thor (1.3.0) thread_safe (0.3.6) tilt (2.3.0) - timeout (0.4.0) + timeout (0.4.1) tomlrb (2.0.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -825,7 +825,7 @@ DEPENDENCIES web-console RUBY VERSION - ruby 3.0.6p216 + ruby 3.0.4p208 BUNDLED WITH 2.4.21 diff --git a/lib/decidim/decidim_awesome/test/factories.rb b/lib/decidim/decidim_awesome/test/factories.rb index 5a928cd..2af3cfa 100644 --- a/lib/decidim/decidim_awesome/test/factories.rb +++ b/lib/decidim/decidim_awesome/test/factories.rb @@ -23,13 +23,6 @@ organization { create :organization } end - factory :paper_trail_version, class: Decidim::DecidimAwesome::PaperTrailVersion do - item_id { user.id } - item_type { "Decidim::ParticipatoryProcessUserRole" } - event { "create" } - created_at { 1.hour.ago } - end - factory :map_component, parent: :component do name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :proposals).i18n_name } manifest_name { :awesome_map } diff --git a/spec/cells/content_blocks/map_cell_spec.rb b/spec/cells/content_blocks/map_cell_spec.rb deleted file mode 100644 index 5479eff..0000000 --- a/spec/cells/content_blocks/map_cell_spec.rb +++ /dev/null @@ -1,120 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe ContentBlocks::MapCell, type: :cell do - subject { cell(content_block.cell, content_block).call } - - let(:organization) { create(:organization) } - let(:content_block) { create :content_block, organization: organization, manifest_name: :awesome_map, scope_name: :homepage, settings: settings } - let(:settings) { {} } - let!(:participatory_process) { create :participatory_process, organization: organization } - let!(:category) { create :category, participatory_space: participatory_process } - let!(:proposal_component) { create :proposal_component, :with_geocoding_enabled, participatory_space: participatory_process } - let!(:meeting_component) { create :meeting_component, participatory_space: participatory_process } - let!(:proposal) { create :proposal, component: proposal_component } - let!(:meeting) { create :meeting, component: meeting_component } - - controller Decidim::PagesController - - before do - allow(controller).to receive(:current_organization).and_return(organization) - end - - it "shows the map" do - expect(subject).to have_selector("#awesome-map") - expect(subject).to have_content("window.AwesomeMap.categories") - end - - it "do not show the title" do - expect(subject).not_to have_selector("h3.section-heading") - end - - it "uses default height" do - expect(subject).to have_content("height: 500px;") - end - - it "uses default data-options" do - expect(subject.to_s).to include('data-truncate="255"') - expect(subject.to_s).to include('data-map-center=""') - expect(subject.to_s).to include('data-map-zoom="8"') - expect(subject.to_s).to include('data-menu-amendments="true"') - expect(subject.to_s).to include('data-menu-meetings="true"') - expect(subject.to_s).to include('data-show-not-answered="true"') - expect(subject.to_s).to include('data-show-accepted="true"') - expect(subject.to_s).to include('data-show-evaluating="true"') - expect(subject.to_s).to include('data-show-withdrawn="false"') - expect(subject.to_s).to include('data-show-rejected="false"') - end - - it "uses all components" do - components = JSON.parse(subject.to_s.match(/data-components='(.*)'/)[1]) - - expect(components.pluck("id")).to include(meeting_component.id) - expect(components.pluck("id")).to include(proposal_component.id) - end - - it "uses all categories" do - categories = JSON.parse(subject.to_s.match(/window\.AwesomeMap\.categories = (\[.*\])/)[1]) - - expect(categories.pluck("id")).to include(category.id) - end - - context "when the content block has a title" do - let(:settings) do - { - "title" => { "en" => "Look this beautiful map!" } - } - end - - it "shows the title" do - expect(subject).to have_selector("h3.section-heading") - expect(subject).to have_content("Look this beautiful map!") - end - end - - context "when a height is defined" do - let(:settings) do - { - map_height: 734 - } - end - - it "uses default height" do - expect(subject).not_to have_content("height: 500px;") - expect(subject).to have_content("height: 734px;") - end - end - - context "when data-options are customized" do - let(:settings) do - { - truncate: 123, - map_center: "41.1,2.3", - map_zoom: 12, - menu_amendments: false, - menu_meetings: false, - show_not_answered: false, - show_accepted: false, - show_evaluating: false, - show_withdrawn: true, - show_rejected: true - } - end - - it "uses default data-options" do - expect(subject.to_s).to include('data-truncate="123"') - expect(subject.to_s).to include('data-map-center="41.1,2.3"') - expect(subject.to_s).to include('data-map-zoom="12"') - expect(subject.to_s).to include('data-menu-amendments="false"') - expect(subject.to_s).to include('data-menu-meetings="false"') - expect(subject.to_s).to include('data-show-not-answered="false"') - expect(subject.to_s).to include('data-show-accepted="false"') - expect(subject.to_s).to include('data-show-evaluating="false"') - expect(subject.to_s).to include('data-show-withdrawn="true"') - expect(subject.to_s).to include('data-show-rejected="true"') - end - end - end -end diff --git a/spec/cells/voting/voting_cards_base_cell_spec.rb b/spec/cells/voting/voting_cards_base_cell_spec.rb deleted file mode 100644 index 1a917ce..0000000 --- a/spec/cells/voting/voting_cards_base_cell_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module DecidimAwesome - module Voting - describe VotingCardsBaseCell, type: :cell do - subject { cell("decidim/decidim_awesome/voting/voting_cards_base", proposal, context: { current_user: user }) } - - let(:manifest) { :voting_cards } - let!(:organization) { create :organization } - let(:user) { create(:user, :confirmed, organization: organization) } - let!(:component) { create :proposal_component, :with_votes_enabled, organization: organization, settings: { awesome_voting_manifest: manifest } } - let(:proposal) { create(:proposal, component: component) } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let!(:vote_weights) do - [ - create_list(:awesome_vote_weight, 3, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create_list(:awesome_vote_weight, 2, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create_list(:awesome_vote_weight, 1, vote: create(:proposal_vote, proposal: proposal), weight: 3) - ] - end - - describe "#proposal" do - it "returns the model" do - expect(subject.proposal).to eq(proposal) - end - end - - describe "#current_component" do - it "returns the component of the proposal" do - expect(subject.current_component).to eq(component) - end - end - - describe "#current_vote" do - context "when user has voted" do - before do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1) - end - - it "returns the current vote of the user for the proposal" do - expect(subject.current_vote).to be_present - end - end - - context "when user has not voted" do - it "returns nil" do - expect(subject.current_vote).to be_nil - end - end - end - end - end - end -end diff --git a/spec/cells/voting/voting_cards_counter_cell_spec.rb b/spec/cells/voting/voting_cards_counter_cell_spec.rb deleted file mode 100644 index ad2230f..0000000 --- a/spec/cells/voting/voting_cards_counter_cell_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module DecidimAwesome - module Voting - describe VotingCardsCounterCell, type: :cell do - subject { cell("decidim/decidim_awesome/voting/voting_cards_counter", proposal, context: { current_user: user }) } - - let(:manifest) { :voting_cards } - let!(:organization) { create :organization } - let(:user) { create(:user, :confirmed, organization: organization) } - let!(:component) { create :proposal_component, :with_votes_enabled, organization: organization, settings: { awesome_voting_manifest: manifest } } - let(:proposal) { create(:proposal, component: component) } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let!(:vote_weights) do - [ - create_list(:awesome_vote_weight, 3, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create_list(:awesome_vote_weight, 2, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create_list(:awesome_vote_weight, 1, vote: create(:proposal_vote, proposal: proposal), weight: 3) - ] - end - - describe "#user_voted_weight" do - context "when user has voted" do - before do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1) - end - - it "returns the weight of the user's vote for the proposal" do - expect(subject.user_voted_weight).to eq(1) - end - end - - context "when user has not voted" do - it "returns nil" do - expect(subject.user_voted_weight).to be_nil - end - end - end - - describe "#vote_btn_class" do - context "when user has voted with weight" do - [0, 1, 2, 3].each do |weight| - it "returns 'weight_#{weight}'" do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: weight) - expect(subject.vote_btn_class).to eq("weight_#{weight}") - end - end - end - - context "when user has not voted" do - it "returns 'hollow'" do - expect(subject.vote_btn_class).to eq("hollow") - end - end - end - end - end - end -end diff --git a/spec/cells/voting/voting_cards_proposal_cell_spec.rb b/spec/cells/voting/voting_cards_proposal_cell_spec.rb deleted file mode 100644 index e20f0b3..0000000 --- a/spec/cells/voting/voting_cards_proposal_cell_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - module DecidimAwesome - module Voting - describe VotingCardsProposalCell, type: :cell do - subject { cell("decidim/decidim_awesome/voting/voting_cards_proposal", proposal, context: { current_user: user }) } - - let(:manifest) { :voting_cards } - let!(:organization) { create :organization } - let(:user) { create(:user, :confirmed, organization: organization) } - let!(:component) { create :proposal_component, :with_votes_enabled, organization: organization, settings: { awesome_voting_manifest: manifest } } - let(:proposal) { create(:proposal, component: component) } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let!(:vote_weights) do - [ - create_list(:awesome_vote_weight, 3, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create_list(:awesome_vote_weight, 2, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create_list(:awesome_vote_weight, 1, vote: create(:proposal_vote, proposal: proposal), weight: 3) - ] - end - - describe "#proposal_votes" do - it "returns the correct number of votes for a given weight" do - expect(subject.proposal_votes(1)).to eq(3) - expect(subject.proposal_votes(2)).to eq(2) - expect(subject.proposal_votes(3)).to eq(1) - end - end - - describe "#voted_for?" do - context "when user has voted" do - before do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1) - end - - it "returns true for the weight the user has voted for" do - expect(subject.voted_for?(1)).to be(true) - end - - it "returns false for the weights the user has not voted for" do - expect(subject.voted_for?(2)).to be(false) - expect(subject.voted_for?(3)).to be(false) - end - end - end - - describe "#from_proposals_list" do - it "returns the value passed in options" do - cell_with_option = cell("decidim/decidim_awesome/voting/voting_cards_proposal", proposal, current_user: user, from_proposals_list: true) - expect(cell_with_option.from_proposals_list).to be(true) - - cell_without_option = cell("decidim/decidim_awesome/voting/voting_cards_proposal", proposal, current_user: user) - expect(cell_without_option.from_proposals_list).to be_nil - end - end - end - end - end -end diff --git a/spec/commands/admin/create_constraint_spec.rb b/spec/commands/admin/create_constraint_spec.rb deleted file mode 100644 index 8452183..0000000 --- a/spec/commands/admin/create_constraint_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe CreateConstraint do - subject { described_class.new(form) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization, - setting: config - } - end - let(:config) { create :awesome_config, organization: organization } - let(:params) do - { - "participatory_space_manifest" => "some-manifest" - } - end - let(:form) do - ConstraintForm.from_params(params).with_context(context) - end - - describe "when valid" do - before do - allow(form).to receive(:valid?).and_return(true) - end - - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints.first.settings).to eq(params) - end - - context "and adding a repeated config" do - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: params) } - - it "broadcasts :invalid" do - expect { subject.call }.to broadcast(:invalid) - end - end - - context "and adding a non repeated config" do - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: params.merge("test" => 1)) } - - it "broadcasts :invalid" do - expect { subject.call }.to broadcast(:ok) - end - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - let!(:config) do - create(:awesome_config, organization: organization) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints).to eq([]) - end - end - end - end -end diff --git a/spec/commands/admin/create_custom_redirect_spec.rb b/spec/commands/admin/create_custom_redirect_spec.rb deleted file mode 100644 index 5dc6db0..0000000 --- a/spec/commands/admin/create_custom_redirect_spec.rb +++ /dev/null @@ -1,133 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/custom_redirects_contexts" - -module Decidim::DecidimAwesome - module Admin - describe CreateCustomRedirect do - subject { described_class.new(form) } - - include_context "with custom redirects params" - - describe "when valid" do - it "broadcasts :ok and creates a hash" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "and origin includes organization host" do - let(:origin) { "http://#{organization.host}/some-path" } - - it "leaves only the path" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items.first[0]).to eq("/some-path") - end - end - - context "and destination includes organization host" do - let(:destination) { "http://#{organization.host}/some-path" } - - it "do not remove the host" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items.first[1]["destination"]).to eq(destination) - end - end - - context "and origin is malformed" do - let(:origin) { " Some-path " } - - it "is sanitized" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items.first[0]).to eq("/Some-path") - end - end - - context "and destination is malformed" do - let(:destination) { " sOme-path " } - - it "is sanitized" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items.first[1]["destination"]).to eq("/sOme-path") - end - end - - context "and entries already exist" do - let!(:config) do - create :awesome_config, - organization: organization, - var: :custom_redirects, - value: { "/another-redirection" => { destination: "/another-destination", active: true } } - end - - shared_examples "has redirection content" do - it "do not removes previous entries" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items.count).to eq(2) - expect(items[attributes[0]]).to eq(attributes[1]) - expect(items["/another-redirection"]).to eq("destination" => "/another-destination", "active" => true) - end - end - - it_behaves_like "has redirection content" - - context "and another configuration is created" do - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has redirection content" - end - - context "and another configuration is updated" do - let!(:existing_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false } - - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has redirection content" - end - end - end - - describe "when same redirection exists" do - let(:previous_redirection) do - { "/some-path" => { "destination" => "/another-path", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_redirection } - let(:origin) { "/some-path" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(previous_redirection) - end - end - end - end -end diff --git a/spec/commands/admin/create_menu_hack_spec.rb b/spec/commands/admin/create_menu_hack_spec.rb deleted file mode 100644 index 8b229bf..0000000 --- a/spec/commands/admin/create_menu_hack_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/menu_hack_contexts" - -module Decidim::DecidimAwesome - module Admin - describe CreateMenuHack do - subject { described_class.new(form, menu_name) } - - include_context "with menu hacks params" - - describe "when valid" do - it "broadcasts :ok and creates an array" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items).to be_a(Array) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "and url includes organization host" do - let(:url) { "http://#{organization.host}/some-path" } - - it "leaves only the path" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items.first["url"]).to eq("/some-path") - end - end - - context "and entries already exist" do - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: [{ url: "/another-menu", position: 10 }] } - - shared_examples "has menu content" do - it "do not removes previous entries" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value.sort_by { |i| i["position"] } - expect(items.count).to eq(2) - expect(items.first).to eq(attributes) - expect(items.second).to eq("url" => "/another-menu", "position" => 10) - end - end - - it_behaves_like "has menu content" - - context "and another configuration is created" do - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has menu content" - end - - context "and another configuration is updated" do - let!(:existing_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false } - - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has menu content" - end - end - end - - describe "when same menu exists" do - let(:previous_menu) do - [{ "url" => "/some-path", "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let(:url) { "/some-path?querystring" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(previous_menu) - end - end - end - end -end diff --git a/spec/commands/admin/create_proposal_custom_field_spec.rb b/spec/commands/admin/create_proposal_custom_field_spec.rb deleted file mode 100644 index 2f034fa..0000000 --- a/spec/commands/admin/create_proposal_custom_field_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe CreateProposalCustomField do - subject { described_class.new(organization) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization - } - end - let(:params) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - let(:form) do - ConfigForm.from_params(params).with_context(context) - end - let(:another_config) { UpdateConfig.new(form) } - - describe "when valid" do - it "broadcasts :ok and creates a Hash" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys.count).to eq(1) - end - - context "and entries already exist" do - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: { test: '[{"type":"text","required":true,"label":"Age","name":"age"}]' } } - - shared_examples "has css boxes content" do - it "do not removes previous entries" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys.count).to eq(2) - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.values).to include('[{"type":"text","required":true,"label":"Age","name":"age"}]') - end - end - - it_behaves_like "has css boxes content" - - context "and another configuration is created" do - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has css boxes content" - end - - context "and another configuration is updated" do - let!(:existing_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false } - - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has css boxes content" - end - end - end - - describe "when invalid" do - subject { described_class.new("nonsense") } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields)).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/create_scoped_admin_spec.rb b/spec/commands/admin/create_scoped_admin_spec.rb deleted file mode 100644 index b004319..0000000 --- a/spec/commands/admin/create_scoped_admin_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe CreateScopedAdmin do - subject { described_class.new(organization) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization - } - end - let(:params) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - let(:form) do - ConfigForm.from_params(params).with_context(context) - end - let(:another_config) { UpdateConfig.new(form) } - let(:scoped_admins) do - AwesomeConfig.find_by(organization: organization, var: :scoped_admins) - end - - shared_examples "create default constraints" do - let(:subconfig) do - AwesomeConfig.find_by(organization: organization, var: "scoped_admin_#{key}") - end - - it "creates a 'none' constraint by default" do - expect { subject.call }.to broadcast(:ok) - expect(subconfig.constraints.count).to eq(1) - expect(subconfig.constraints.first.settings).to eq({ "participatory_space_manifest" => "none" }) - end - end - - describe "when valid" do - it "broadcasts :ok and creates a Hash" do - expect { subject.call }.to broadcast(:ok) - - expect(scoped_admins.value).to be_a(Hash) - expect(scoped_admins.value.keys.count).to eq(1) - end - - it_behaves_like "create default constraints" do - let(:key) { scoped_admins.value.keys.first } - end - - context "and entries already exist" do - let!(:config) { create :awesome_config, organization: organization, var: :scoped_admins, value: { test: [123, 456] } } - - shared_examples "has scoped admin boxes content" do - it "do not removes previous entries" do - expect { subject.call }.to broadcast(:ok) - - expect(scoped_admins.value.keys.count).to eq(2) - expect(scoped_admins.value.values).to include([123, 456]) - end - end - - it_behaves_like "has scoped admin boxes content" - it_behaves_like "create default constraints" do - let(:key) { scoped_admins.value.keys.last } - end - - context "and another configuration is created" do - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has scoped admin boxes content" - end - - context "and another configuration is updated" do - let!(:existing_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false } - - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has scoped admin boxes content" - end - end - end - - describe "when invalid" do - subject { described_class.new("nonsense") } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(scoped_admins).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/create_scoped_style_spec.rb b/spec/commands/admin/create_scoped_style_spec.rb deleted file mode 100644 index c394daa..0000000 --- a/spec/commands/admin/create_scoped_style_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe CreateScopedStyle do - subject { described_class.new(organization) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization - } - end - let(:params) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - let(:form) do - ConfigForm.from_params(params).with_context(context) - end - let(:another_config) { UpdateConfig.new(form) } - - describe "when valid" do - it "broadcasts :ok and creates a Hash" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys.count).to eq(1) - end - - context "and entries already exist" do - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: { test: ".body {background: red;}" } } - - shared_examples "has css boxes content" do - it "do not removes previous entries" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys.count).to eq(2) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.values).to include(".body {background: red;}") - end - end - - it_behaves_like "has css boxes content" - - context "and another configuration is created" do - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has css boxes content" - end - - context "and another configuration is updated" do - let!(:existing_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false } - - before do - another_config.call - end - - it "modifies the other config" do - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it_behaves_like "has css boxes content" - end - end - end - - describe "when invalid" do - subject { described_class.new("nonsense") } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles)).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/destroy_constraint_spec.rb b/spec/commands/admin/destroy_constraint_spec.rb deleted file mode 100644 index 28bead4..0000000 --- a/spec/commands/admin/destroy_constraint_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe DestroyConstraint do - subject { described_class.new(constraint) } - - let(:organization) { create(:organization) } - # let(:context) do - # { - # current_user: create(:user, organization: organization), - # current_organization: organization, - # setting: config - # } - # end - let(:name) { :some_config_var } - let(:config) { create :awesome_config, organization: organization, var: name } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "test" => 1 }) } - - shared_examples "destroys the constraint" do - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints).not_to include(constraint) - end - end - - shared_examples "do not destroy the constraint" do - it "broadcasts :invalid and does not modify the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints).to include(constraint) - end - end - - context "when is not the last constraint" do - let!(:constraint2) { create(:config_constraint, awesome_config: config, settings: { "test2" => 2 }) } - - context "and is a non-critical scope" do - it_behaves_like "destroys the constraint" - end - - context "and is a critical scope" do - let(:name) { :proposal_custom_field } - - it_behaves_like "destroys the constraint" - end - end - - context "when is the last constraint" do - context "and is a non-critical scope" do - it_behaves_like "destroys the constraint" - end - - context "and is a critical scope" do - let(:name) { :proposal_custom_field } - - it_behaves_like "do not destroy the constraint" - end - end - end - end -end diff --git a/spec/commands/admin/destroy_custom_redirect_spec.rb b/spec/commands/admin/destroy_custom_redirect_spec.rb deleted file mode 100644 index a73def7..0000000 --- a/spec/commands/admin/destroy_custom_redirect_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/custom_redirects_contexts" - -# rubocop:disable Style/OpenStructUse -module Decidim::DecidimAwesome - module Admin - describe DestroyCustomRedirect do - subject { described_class.new(item, organization) } - - include_context "with custom redirects params" - - let(:item) { OpenStruct.new({ origin: attributes[0] }.merge(attributes[1])) } - let(:previous_value) do - { "/previous-route" => { "destination" => "/another-place", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: [attributes].to_h.merge(previous_value) } - - describe "when valid" do - it "broadcasts :ok and removes the item" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items["/previous-route"]).to eq(previous_value["/previous-route"]) - end - end - - describe "when invalid" do - let(:item) { OpenStruct.new({ origin: "/not-in-the-list" }.merge(attributes[1])) } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(2) - end - end - end - end -end -# rubocop:enable Style/OpenStructUse diff --git a/spec/commands/admin/destroy_menu_hack_spec.rb b/spec/commands/admin/destroy_menu_hack_spec.rb deleted file mode 100644 index d5ff927..0000000 --- a/spec/commands/admin/destroy_menu_hack_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/menu_hack_contexts" - -# rubocop:disable Style/OpenStructUse -module Decidim::DecidimAwesome - module Admin - describe DestroyMenuHack do - subject { described_class.new(item, menu_name, organization) } - - include_context "with menu hacks params" - - let(:item) { OpenStruct.new(attributes) } - let(:previous_menu) do - { "url" => "/another-link", "position" => 10 } - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: [attributes, previous_menu] } - - describe "when valid" do - it "broadcasts :ok and removes the item" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - - expect(items).to be_a(Array) - expect(items.count).to eq(1) - expect(items.first).to eq(previous_menu) - end - end - - describe "when invalid" do - let(:item) { OpenStruct.new("url" => "/not-in-the-menu") } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items).to be_a(Array) - expect(items.count).to eq(2) - end - end - end - end -end -# rubocop:enable Style/OpenStructUse diff --git a/spec/commands/admin/destroy_proposal_custom_field_spec.rb b/spec/commands/admin/destroy_proposal_custom_field_spec.rb deleted file mode 100644 index bc96f15..0000000 --- a/spec/commands/admin/destroy_proposal_custom_field_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe DestroyProposalCustomField do - subject { described_class.new(key, organization) } - - let(:organization) { create(:organization) } - let(:custom_fields) do - { - foo: '[{"type":"text","required":true,"label":"Age","name":"age"}]', - bar: '[{"type":"textarea","required":true,"label":"Bio","name":"bio"}]' - } - end - let(:key) { "foo" } - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - - describe "when valid" do - it "broadcasts :ok and removes the item" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys.count).to eq(1) - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys).to include("bar") - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.values).to include('[{"type":"textarea","required":true,"label":"Bio","name":"bio"}]') - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.values).not_to include('[{"type":"text","required":true,"label":"Age","name":"age"}]') - end - end - - describe "when invalid" do - let(:key) { "nonsense" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys.count).to eq(2) - end - end - - describe "when has a constraint" do - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_foo } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "test" => 1 }) } - - it "removes the config helper and the constraint" do - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_foo).constraints.count).to eq(1) - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_fields).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_foo)).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/destroy_scoped_admin_spec.rb b/spec/commands/admin/destroy_scoped_admin_spec.rb deleted file mode 100644 index ef6c349..0000000 --- a/spec/commands/admin/destroy_scoped_admin_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe DestroyScopedAdmin do - subject { described_class.new(key, organization) } - - let(:organization) { create(:organization) } - let(:admins) do - { - foo: [123, 456], - bar: [789, 901] - } - end - let(:key) { "foo" } - let!(:config) { create :awesome_config, organization: organization, var: :scoped_admins, value: admins } - - describe "when valid" do - it "broadcasts :ok and removes the item" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.keys.count).to eq(1) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.keys).to include("bar") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.values).to include([789, 901]) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.values).not_to include([123, 456]) - end - end - - describe "when invalid" do - let(:key) { "nonsense" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.keys.count).to eq(2) - end - end - - describe "when has a constraint" do - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_admin_foo } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "test" => 1 }) } - - it "removes the config helper and the constraint" do - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admin_foo).constraints.count).to eq(1) - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admins).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_admin_foo)).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/destroy_scoped_style_spec.rb b/spec/commands/admin/destroy_scoped_style_spec.rb deleted file mode 100644 index caf8b58..0000000 --- a/spec/commands/admin/destroy_scoped_style_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe DestroyScopedStyle do - subject { described_class.new(key, organization) } - - let(:organization) { create(:organization) } - let(:styles) do - { - foo: ".body {background: red;}", - bar: ".body {background: blue;}" - } - end - let(:key) { "foo" } - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: styles } - - describe "when valid" do - it "broadcasts :ok and removes the item" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys.count).to eq(1) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys).to include("bar") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.values).to include(".body {background: blue;}") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.values).not_to include(".body {background: red;}") - end - end - - describe "when invalid" do - let(:key) { "nonsense" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to be_a(Hash) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys.count).to eq(2) - end - end - - describe "when has a constraint" do - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_style_foo } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "test" => 1 }) } - - it "removes the config helper and the constraint" do - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_style_foo).constraints.count).to eq(1) - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value.keys).not_to include("foo") - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_style_foo)).to be_nil - end - end - end - end -end diff --git a/spec/commands/admin/rename_scope_label_spec.rb b/spec/commands/admin/rename_scope_label_spec.rb deleted file mode 100644 index 5a2f24e..0000000 --- a/spec/commands/admin/rename_scope_label_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe RenameScopeLabel do - subject { described_class.new(params, organization) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization, - setting: config - } - end - let(:config) { create :awesome_config, organization: organization, var: attribute, value: value } - let!(:another_config) { create :awesome_config, var: attribute, value: value } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "test" => 1 }) } - let!(:scoped_config) { create :awesome_config, organization: organization, var: scope } - let!(:another_scoped_config) { create :awesome_config, var: scope } - let(:value) do - { - key => "something" - } - end - let(:after_value) do - { - text => "something" - } - end - let(:params) do - { - text: text, - key: key, - attribute: attribute, - scope: scope - } - end - let(:text) { "bar" } - let(:key) { "foo" } - let(:attribute) { "scoped_something" } - let(:scope) { "#{attribute}_#{key}" } - let(:after_scope) { "#{attribute}_#{text}" } - - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: attribute).value).to eq(after_value) - expect(AwesomeConfig.find_by(organization: organization, var: after_scope).id).to eq(scoped_config.id) - expect(AwesomeConfig.find_by(organization: organization, var: scope)).to be_nil - expect(AwesomeConfig.find(another_config.id).value).to eq(value) - expect(AwesomeConfig.find(another_scoped_config.id).var).to eq(scope) - end - - describe "when empty" do - let(:text) { " " } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: attribute).value).to eq(value) - expect(AwesomeConfig.find_by(organization: organization, var: scope).id).to eq(scoped_config.id) - expect(AwesomeConfig.find_by(organization: organization, var: after_scope)).to be_nil - end - end - - describe "when key repeated" do - let(:text) { "foo" } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: attribute).value).to eq(value) - expect(AwesomeConfig.find_by(organization: organization, var: scope).id).to eq(scoped_config.id) - end - end - - describe "when no config" do - let(:config) { nil } - let(:constraint) { nil } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - end - end - - describe "when no scoped_config" do - let(:scoped_config) { nil } - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:ok) - end - end - end - end -end diff --git a/spec/commands/admin/update_config_spec.rb b/spec/commands/admin/update_config_spec.rb deleted file mode 100644 index 15dbfb2..0000000 --- a/spec/commands/admin/update_config_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe UpdateConfig do - subject { described_class.new(form) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization - } - end - let(:params) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - let(:form) do - ConfigForm.from_params(params).with_context(context) - end - - describe "when valid" do - before do - allow(form).to receive(:valid?).and_return(true) - end - - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - let!(:config) do - create(:awesome_config, organization: organization, var: :allow_images_in_full_editor, value: false) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(false) - end - end - - describe "when updating CSS" do - let!(:config) { create :awesome_config, organization: organization, var: "scoped_styles", value: { test: ".body {background: red;}" } } - - it "saves the content in the hash" do - expect(AwesomeConfig.find_by(organization: organization, var: "scoped_styles").value).to be_a(Hash) - end - - # context "and has a constraint" do - # it "creates an associated config constraint var" do - # end - # end - end - end - end -end diff --git a/spec/commands/admin/update_constraint_spec.rb b/spec/commands/admin/update_constraint_spec.rb deleted file mode 100644 index fab5c32..0000000 --- a/spec/commands/admin/update_constraint_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe UpdateConstraint do - subject { described_class.new(form) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_user: create(:user, organization: organization), - current_organization: organization, - setting: config - } - end - let(:config) { create :awesome_config, organization: organization } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "test" => 1 }) } - let(:params) do - settings.merge("id" => constraint.id) - end - let(:settings) do - { - "participatory_space_manifest" => "some-manifest" - } - end - let(:form) do - ConstraintForm.from_params(params).with_context(context) - end - - describe "when valid" do - before do - allow(form).to receive(:valid?).and_return(true) - end - - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints.first.settings).to eq(settings) - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: config.var).constraints.first.settings).to eq("test" => 1) - end - end - end - end -end diff --git a/spec/commands/admin/update_custom_redirect_spec.rb b/spec/commands/admin/update_custom_redirect_spec.rb deleted file mode 100644 index 3230b34..0000000 --- a/spec/commands/admin/update_custom_redirect_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/custom_redirects_contexts" - -module Decidim::DecidimAwesome - module Admin - describe UpdateCustomRedirect do - subject { described_class.new(form, item) } - - include_context "with custom redirects params" - - let(:item) { double(params) } - let(:previous_value) do - { origin => { "destination" => "/previous-redirection", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_value } - - describe "when valid" do - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(previous_value) - end - end - - context "when other config are created" do - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: attributes } - - it "modifies the other config" do - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it "do not modifiy current config" do - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(attributes) - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(attributes) - end - end - - context "when updating an non existing redirection" do - let(:previous_value) do - { "/another-origin" => { "destination" => "/another-redirection", "active" => true } } - end - - it "do not modifiy current config" do - expect { subject.call }.to broadcast(:invalid) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items).to eq(previous_value) - end - end - - context "when there's several items" do - let(:previous_value) do - { - "/another-origin" => { "destination" => "/another-redirection", "active" => true }, - origin => { "destination" => "/some-place-to-go", "active" => true } - } - end - - it "modifies the intended item" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(2) - expect(items).not_to eq(previous_value) - expect(items["/another-origin"]).to eq(previous_value["/another-origin"]) - expect(items[attributes[0]]).to eq(attributes[1]) - end - - context "when changing the origin" do - let(:item) do - double( - origin: origin, - destination: destination, - active: active, - pass_query: pass_query - ) - end - let(:params) do - { - origin: "/a-new-origin", - destination: "/a-new-destination", - active: active, - pass_query: pass_query - } - end - - it "removes the old, puts the new" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(2) - expect(items).not_to eq(previous_value) - expect(items["/another-origin"]).to eq(previous_value["/another-origin"]) - expect(items["/a-new-origin"]["destination"]).to eq(params[:destination]) - end - end - end - end - end -end diff --git a/spec/commands/admin/update_menu_hack_spec.rb b/spec/commands/admin/update_menu_hack_spec.rb deleted file mode 100644 index 1f6c1b7..0000000 --- a/spec/commands/admin/update_menu_hack_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/menu_hack_contexts" - -module Decidim::DecidimAwesome - module Admin - describe UpdateMenuHack do - subject { described_class.new(form, menu_name) } - - include_context "with menu hacks params" - - let(:previous_menu) do - [{ "url" => url, "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - - describe "when valid" do - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items).to be_a(Array) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - expect(items.first["url"]).to eq(url) - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(previous_menu) - end - end - - context "when other config are created" do - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: attributes } - - it "modifies the other config" do - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it "do not modifiy current config" do - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(attributes) - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(attributes) - end - end - - context "when updating an non existing menu" do - let(:previous_menu) do - [{ "url" => "/another-menu", "position" => 10 }] - end - - it "adds a new menu entry" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value.sort_by { |i| i["position"] } - expect(items).to be_a(Array) - expect(items.count).to eq(2) - expect(items.first).to eq(attributes) - expect(items.first["url"]).to eq(url) - expect(items.second).to eq(previous_menu.first) - end - end - - context "when updating an native menu" do - let(:previous_menu) do - [{ "url" => "/another-menu", "position" => 10 }] - end - let(:url) { "/another-menu?querystring" } - let(:params) do - { - raw_label: label, - url: url, - position: position, - target: target, - visibility: visibility, - native?: true - } - end - - it "adds a new menu entry" do - expect { subject.call }.to broadcast(:ok) - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value.sort_by { |i| i["position"] } - expect(items).to be_a(Array) - expect(items.count).to eq(2) - expect(items.first["url"]).to eq(url) - expect(items.second["url"]).to eq("/another-menu") - end - end - end - end -end diff --git a/spec/commands/admin/update_scoped_styles.rb b/spec/commands/admin/update_scoped_styles.rb deleted file mode 100644 index c01bcae..0000000 --- a/spec/commands/admin/update_scoped_styles.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe UpdateConfig do - subject { described_class.new(form) } - - let(:organization) { create(:organization) } - let(:context) do - { - current_organization: organization - } - end - let(:params) do - { - scoped_styles: styles - } - end - let(:styles) do - { - "foo" => ".body {background: red;}", - "bar" => ".body {background: blue;}" - } - end - let(:oldstyles) do - { - "foo" => "", - "bar" => "" - } - end - let(:form) do - ConfigForm.from_params(params).with_context(context) - end - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: oldstyles } - let(:params2) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - let(:form2) do - ConfigForm.from_params(params2).with_context(context) - end - let(:another_config) { UpdateConfig.new(form2) } - - describe "when valid" do - before do - allow(form).to receive(:valid?).and_return(true) - end - - it "broadcasts :ok and modifies the config options" do - expect { subject.call }.to broadcast(:ok) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to eq(styles) - end - end - - describe "when invalid" do - before do - allow(form).to receive(:valid?).and_return(false) - end - - it "broadcasts :invalid and does not modifiy the config options" do - expect { subject.call }.to broadcast(:invalid) - - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to eq(oldstyles) - end - end - - context "when other config are created" do - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: styles } - - it "modifies the other config" do - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_full_editor).value).to be(true) - expect(AwesomeConfig.find_by(organization: organization, var: :allow_images_in_small_editor).value).to be(true) - end - - it "do not modifiy current config" do - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to eq(styles) - expect { another_config.call }.to broadcast(:ok) - expect(AwesomeConfig.find_by(organization: organization, var: :scoped_styles).value).to eq(styles) - end - end - end - end -end diff --git a/spec/controllers/admin/admin_accountability_controller_spec.rb b/spec/controllers/admin/admin_accountability_controller_spec.rb deleted file mode 100644 index b9a417b..0000000 --- a/spec/controllers/admin/admin_accountability_controller_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe AdminAccountabilityController, type: :controller do - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - let(:admin_accountability) { [:participatory_space_roles, :admin_roles] } - - before do - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - - allow(Decidim::DecidimAwesome.config).to receive(:admin_accountability).and_return(admin_accountability) - end - - describe "GET #index" do - context "when admin accountability is enabled" do - it "returns http success" do - get :index, params: {} - expect(response).to have_http_status(:success) - end - - it "returns http success for globa admins" do - get :index, params: { admins: true } - expect(response).to have_http_status(:success) - end - end - - context "when admin accountability is disabled" do - let!(:admin_accountability) { :disabled } - - it "returns http redirect" do - get :index, params: {} - expect(response).to have_http_status(:redirect) - end - - it "returns http redirect for globa admins" do - get :index, params: { admins: true } - expect(response).to have_http_status(:redirect) - end - end - - context "when admin accountability is for spaces only" do - let!(:admin_accountability) { [:participatory_space_roles] } - - it "returns http success" do - get :index, params: {} - expect(response).to have_http_status(:success) - end - - it "returns http success for globa admins" do - get :index, params: { admins: true } - expect(response).to have_http_status(:redirect) - end - end - - context "when admin accountability is for admins only" do - let!(:admin_accountability) { [:admin_roles] } - - it "returns http success" do - get :index, params: {} - expect(response).to have_http_status(:redirect) - end - - it "returns http success for globa admins" do - get :index, params: { admins: true } - expect(response).to have_http_status(:success) - end - end - end - end - end -end diff --git a/spec/controllers/admin/checks_controller_spec.rb b/spec/controllers/admin/checks_controller_spec.rb deleted file mode 100644 index f8c8cc2..0000000 --- a/spec/controllers/admin/checks_controller_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe ChecksController, type: :controller do - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - - before do - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - shared_examples "valid decidim version" do - it "is a valid Decidim version" do - expect(controller.helpers.decidim_version_valid?).to be(true) - end - - it "has a list of overrides" do - expect(controller.helpers.overrides.count > 0).to be(true) - end - - it "all overrides are valid" do - controller.helpers.overrides.each do |_group, props| - props.files.each do |file, _md5| - expect(controller.helpers.valid?(props.spec, file)).not_to be_nil - end - end - end - end - - shared_examples "invalid decidim version" do - it "is not a valid Decidim version" do - expect(controller.helpers.decidim_version_valid?).to be(false) - end - - it "has a list of overrides" do - expect(controller.helpers.overrides.count > 0).to be(true) - end - end - - describe "GET #index" do - it "returns http success" do - get :index, params: {} - expect(response).to have_http_status(:success) - end - - it_behaves_like "valid decidim version" - - context "when other Decidim versions" do - before do - allow(Decidim).to receive(:version).and_return(version) - end - - context "and is lower than supported" do - let(:version) { "0.25.1" } - - it_behaves_like "invalid decidim version" - end - - context "and is higher than supported" do - let(:version) { "0.28" } - - it_behaves_like "invalid decidim version" - end - end - end - - describe "GET #migrate_images" do - it "returns http success" do - post :migrate_images, params: {} - expect(response).to have_http_status(:redirect) - end - end - end - end -end diff --git a/spec/controllers/admin/components_controller_spec.rb b/spec/controllers/admin/components_controller_spec.rb deleted file mode 100644 index 6ffb704..0000000 --- a/spec/controllers/admin/components_controller_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Assemblies - module Admin - describe ComponentsController, type: :controller do - routes { Decidim::Assemblies::AdminEngine.routes } - - let(:organization) { create(:organization) } - let(:current_user) { create(:user, :confirmed, :admin, organization: organization) } - let!(:assembly) do - create( - :assembly, - :published, - organization: organization - ) - end - let(:component) do - create( - :proposal_component, - participatory_space: assembly - ) - end - let(:manifest) { :voting_cards } - - before do - request.env["decidim.current_organization"] = organization - request.env["decidim.current_assembly"] = assembly - sign_in current_user - end - - describe "PATCH update" do - let(:component_params) do - { - name_en: "Proposals component", - settings: { - awesome_voting_manifest: manifest - } - } - end - - it "changes the voting manifest" do - patch :update, params: { assembly_slug: assembly.slug, id: component.id, component: component_params } - - expect(component.reload.settings.awesome_voting_manifest).to eq("voting_cards") - expect(response).to redirect_to components_path - end - - context "when votes exist" do - let!(:vote) { create :proposal_vote, proposal: proposal } - let(:proposal) { create :proposal, component: component } - - it "does not change the voting manifest" do - patch :update, params: { assembly_slug: assembly.slug, id: component.id, component: component_params } - - expect(component.reload.settings.awesome_voting_manifest).to eq("") - expect(response).to redirect_to components_path - end - end - end - end - end -end diff --git a/spec/controllers/admin/config_controller_spec.rb b/spec/controllers/admin/config_controller_spec.rb deleted file mode 100644 index 1dc0f70..0000000 --- a/spec/controllers/admin/config_controller_spec.rb +++ /dev/null @@ -1,216 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" - -module Decidim::DecidimAwesome - module Admin - describe ConfigController, type: :controller do - include Decidim::TranslationsHelper - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - let(:config) do - { - allow_images_in_full_editor: false, - allow_images_in_small_editor: false - } - end - let(:params) do - { - var: :editors - } - end - - before do - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - describe "GET #show" do - it "returns http success" do - get :show, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:features) { Decidim::DecidimAwesome.config.keys } - let(:action) { get :show, params: params } - end - - context "when params var is empty" do - let(:params) { {} } - let(:editors) { [:allow_images_in_full_editor, :allow_images_in_small_editor, :use_markdown_editor, :allow_images_in_markdown_editor] } - let(:disabled) { [] } - - before do - disabled.each do |feat| - allow(Decidim::DecidimAwesome.config).to receive(feat).and_return(:disabled) - end - end - - it "returns editors" do - expect(controller.helpers.config_var).to eq(:editors) - end - - context "when editors is disabled" do - let(:disabled) { editors } - - it "returns proposals" do - expect(controller.helpers.config_var).to eq(:proposals) - end - - context "and proposals is disabled" do - let(:disabled) do - editors + [:allow_images_in_proposals, - :validate_title_min_length, - :validate_title_max_caps_percent, - :validate_title_max_marks_together, - :validate_title_start_with_caps, - :validate_body_min_length, - :validate_body_max_caps_percent, - :validate_body_max_marks_together, - :validate_body_start_with_caps] - end - - it "returns surveys" do - expect(controller.helpers.config_var).to eq(:surveys) - end - end - end - end - - context "when constraint exists" do - let(:key) { :allow_images_in_full_editor } - let(:settings) do - { - participatory_space_manifest: manifest, - participatory_space_slug: slug, - component_manifest: component_manifest, - component_id: id - } - end - let(:manifest) { process.manifest.name } - let(:slug) { process.slug } - let(:component_manifest) { component.manifest.name } - let(:id) { component.id } - let!(:config) { create(:awesome_config, organization: organization, var: key) } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: settings) } - let!(:process) { create :participatory_process, organization: organization } - let!(:component) { create :component, participatory_space: process } - - it "sumarizes the scope for process manifest" do - expect(controller.helpers.translate_constraint_value(constraint, "participatory_space_manifest")).to eq("Processes") - end - - it "sumarizes the scope for process slug" do - expect(controller.helpers.translate_constraint_value(constraint, "participatory_space_slug")).to eq(translated_attribute(process.title)) - end - - it "sumarizes the scope for component manifest" do - expect(controller.helpers.translate_constraint_value(constraint, "component_manifest")).to eq("Dummy Component") - end - - it "sumarizes the scope for component id" do - expect(controller.helpers.translate_constraint_value(constraint, "component_id")).to eq("#{id}: #{translated_attribute(component.name)}") - end - - context "when unknown keys" do - let(:id) { "dummy" } - - it "sumarizes the value" do - expect(controller.helpers.translate_constraint_value(constraint, "component_id")).to eq("dummy") - end - end - end - end - - describe "PATCH #update" do - let(:params) do - { - var: :editors, - config: { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - } - end - - it "redirects as success success" do - get :update, params: params - expect(response).to have_http_status(:redirect) - end - - it_behaves_like "forbids disabled feature" do - let(:features) { config.keys } - let(:action) { get :show, params: params } - end - end - - describe "GET #users" do - let(:params) do - {} - end - - it "raises unkown format" do - expect do - get :users, params: params - end.to raise_exception(ActionController::UnknownFormat) - end - - context "when format is json" do - it "retuns a list of users" do - get :users, params: params, format: :json - expect(response).to have_http_status(:ok) - end - end - end - - describe "POST #rename_scope_label" do - let(:params) do - {} - end - - it "returns invalid" do - post :rename_scope_label, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - - context "when data is present" do - let(:params) do - { - text: "bar", - key: "foo", - scope: "scoped_something_foo", - attribute: "scoped_something" - } - end - - it "returns invalid" do - post :rename_scope_label, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - - context "and config exists" do - let!(:config) { create :awesome_config, organization: organization, var: "scoped_something", value: { "foo" => "something" } } - - it "retuns ok" do - post :rename_scope_label, params: params - expect(response).to have_http_status(:ok) - end - - context "and is in another organization" do - let!(:config) { create :awesome_config, var: "scoped_something", value: { "foo" => "something" } } - - it "returns invalid" do - post :rename_scope_label, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - end - end - end - end - end - end -end diff --git a/spec/controllers/admin/constraints_controller_spec.rb b/spec/controllers/admin/constraints_controller_spec.rb deleted file mode 100644 index 8781df3..0000000 --- a/spec/controllers/admin/constraints_controller_spec.rb +++ /dev/null @@ -1,171 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" - -module Decidim::DecidimAwesome - module Admin - describe ConstraintsController, type: :controller do - include Decidim::TranslationsHelper - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - let(:config) { create(:awesome_config, organization: organization, var: key) } - let(:constraint) { create(:config_constraint, awesome_config: config) } - let(:key) { :allow_images_in_full_editor } - let(:id) { nil } - let(:params) do - { - key: key, - id: id, - participatory_space_manifest: "assemblies" - } - end - let(:spaces) do - [ - [process.slug, translated_attribute(process.title)] - ].to_h - end - let(:components) do - [ - [component.id, "#{component.id}: #{translated_attribute(component.name)}"] - ].to_h - end - - before do - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - describe "GET #new" do - it "returns http success" do - get :new, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:feature) { key } - let(:action) { get :new, params: params } - end - - it "has helper with participatory space manifests" do - expect(controller.helpers.participatory_space_manifests).to include(:participatory_processes) - expect(controller.helpers.participatory_space_manifests).to include(:assemblies) - end - - it "has helper with component manifests" do - expect(controller.helpers.component_manifests).to include(:proposals) - expect(controller.helpers.component_manifests).to include(:meetings) - expect(controller.helpers.component_manifests).to include(:awesome_map) - expect(controller.helpers.component_manifests).to include(:awesome_iframe) - end - - context "when participatory process exists" do - let!(:process) { create :participatory_process, organization: organization } - let!(:component) { create :component, participatory_space: process } - - it "has helper with existing participatory spaces" do - expect(controller.helpers.participatory_spaces_list(:participatory_processes)).to eq(spaces) - end - - it "has helper with existing components" do - expect(controller.helpers.components_list(:participatory_processes, process.slug)).to eq(components) - end - end - - context "when process is in another organization" do - let!(:process) { create :participatory_process } - - it "has empty helpers" do - expect(controller.helpers.participatory_spaces_list(:participatory_processes)).to eq({}) - expect(controller.helpers.components_list(:participatory_processes, process.slug)).to eq({}) - end - end - - context "when key is scoped_style" do - let(:key) { :scoped_style_test } - - it "returns http success" do - get :new, params: params - expect(response).to have_http_status(:success) - end - end - end - - describe "POST #create" do - it "returns a success response" do - post :create, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:feature) { key } - let(:action) { post :create, params: params } - end - - context "when wrong params" do - before do - allow(controller).to receive(:current_setting).and_return(double(var: "some-var")) - end - - it "returns error" do - get :create, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - end - end - - describe "GET #show" do - let(:id) { constraint.id } - - it "returns http success" do - get :show, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:feature) { key } - let(:action) { get :show, params: params } - end - end - - describe "PATCH #update" do - let(:id) { constraint.id } - - it "redirects as success success" do - patch :update, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:feature) { key } - let(:action) { patch :update, params: params } - end - - context "when wrong params" do - let!(:prev_constraint) { create :config_constraint, awesome_config: config, settings: { participatory_space_manifest: "assemblies" } } - - it "returns error" do - get :update, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - end - end - - describe "PATCH #destroy" do - let(:id) { constraint.id } - - it "redirects as success success" do - delete :destroy, params: params - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:feature) { key } - let(:action) { delete :destroy, params: params } - end - end - end - end -end diff --git a/spec/controllers/admin/custom_redirects_controller_spec.rb b/spec/controllers/admin/custom_redirects_controller_spec.rb deleted file mode 100644 index 87b7760..0000000 --- a/spec/controllers/admin/custom_redirects_controller_spec.rb +++ /dev/null @@ -1,218 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" -require "decidim/decidim_awesome/test/shared_examples/custom_redirects_contexts" - -module Decidim::DecidimAwesome - module Admin - describe CustomRedirectsController, type: :controller do - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - include_context "with custom redirects params" - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - - before do - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - describe "GET #new" do - it "returns http success" do - get :new - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:action) { get :new } - end - end - - describe "POST #create" do - let(:action) { post :create, params: params } - - it "returns http success" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it_behaves_like "forbids disabled feature" - - it "creates the new redirection entry" do - action - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "when invalid parameters" do - let(:origin) { "" } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new redirection entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects)).not_to be_present - end - end - - context "when same url exists" do - let(:previous_value) do - { "/some-path" => { "destination" => "/assemblies", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_value } - let(:origin) { "/some-path" } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new redirection entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value.count).to eq(1) - end - end - end - - describe "GET #edit" do - let(:action) { get :edit, params: params } - let(:previous_value) do - { origin => { "destination" => "/assemblies", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_value } - let(:params) do - { - id: Digest::MD5.hexdigest(origin) - } - end - - it "returns http success" do - action - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" - - context "when editing a non existing redirection" do - let(:params) do - { - id: "nonsense" - } - end - - it "returns error" do - expect { action }.to raise_error(ActiveRecord::RecordNotFound) - end - end - end - - describe "PATCH #update" do - let(:action) { patch :update, params: params.merge(id) } - let(:previous_value) do - { origin => { "destination" => "/assemblies", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_value } - let(:id) do - { - id: Digest::MD5.hexdigest(origin) - } - end - - it_behaves_like "forbids disabled feature" - - it "returns http success" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it "updates the redirection entry" do - action - - items = AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value - expect(items).to be_a(Hash) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "when updating a non existing redirection" do - let(:previous_value) do - { "/another-redirection" => { "destination" => "/assemblies", "active" => true } } - end - - it "returns error" do - expect { action }.to raise_error(ActiveRecord::RecordNotFound) - end - end - - context "when invalid parameters" do - let(:origin) { "" } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new redirection entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(previous_value) - end - end - end - - describe "DELETE #destroy" do - let(:action) { delete :destroy, params: params } - let(:previous_value) do - { origin => { "destination" => "/assemblies", "active" => true } } - end - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: previous_value } - let(:params) do - { - id: Digest::MD5.hexdigest(origin) - } - end - - it "returns ok" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it_behaves_like "forbids disabled feature" - - it "destroy the task" do - action - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq({}) - end - - context "when invalid parameters" do - let(:params) do - { - id: "nonsense" - } - end - - it "returns error" do - expect { action }.to raise_error(ActiveRecord::RecordNotFound) - expect(AwesomeConfig.find_by(organization: organization, var: :custom_redirects).value).to eq(previous_value) - end - end - end - end - end -end diff --git a/spec/controllers/admin/menu_hacks_controller_spec.rb b/spec/controllers/admin/menu_hacks_controller_spec.rb deleted file mode 100644 index 08bad07..0000000 --- a/spec/controllers/admin/menu_hacks_controller_spec.rb +++ /dev/null @@ -1,249 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" -require "decidim/decidim_awesome/test/shared_examples/menu_hack_contexts" - -module Decidim::DecidimAwesome - module Admin - describe MenuHacksController, type: :controller do - include Decidim::TranslationsHelper - routes { Decidim::DecidimAwesome::AdminEngine.routes } - - include_context "with menu hacks params" - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - - before do - Decidim::MenuRegistry.register :menu do |menu| - menu.add_item :native_menu, - "Native", - "/processes?locale=ca", - position: 1 - end - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - after do - Decidim::MenuRegistry.find(:menu).configurations.pop - end - - describe "GET #new" do - it "returns http success" do - get :new - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" do - let(:action) { get :new } - end - end - - describe "POST #create" do - let(:action) { post :create, params: params } - - it "returns http success" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it_behaves_like "forbids disabled feature" - - it "creates the new menu entry" do - action - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items).to be_a(Array) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "when invalid parameters" do - let(:label) { { en: "" } } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new menu entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: menu_name)).not_to be_present - end - end - - context "when same url exists" do - let(:previous_menu) do - [{ "url" => "/some-path", "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let(:url) { "/some-path?querystring" } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new menu entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value.count).to eq(1) - end - end - end - - describe "GET #edit" do - let(:action) { get :edit, params: params } - let(:previous_menu) do - [{ "url" => url, "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let(:params) do - { - id: Digest::MD5.hexdigest(previous_menu.first["url"]) - } - end - - it "returns http success" do - action - expect(response).to have_http_status(:success) - end - - it_behaves_like "forbids disabled feature" - - context "when editing a non existing menu" do - let(:params) do - { - id: "nonsense" - } - end - - it "returns error" do - expect { action }.to raise_error(ActiveRecord::RecordNotFound) - end - end - - context "when editing a native menu" do - let(:url) { "/processes?locale=ca" } - let(:params) do - { - id: Digest::MD5.hexdigest(url) - } - end - - it "removes the querystring" do - action - - expect(controller.instance_variable_get(:@form).url).to eq("/processes") - expect(response).to have_http_status(:success) - end - end - end - - describe "PATCH #update" do - let(:action) { patch :update, params: params.merge(id) } - let(:previous_menu) do - [{ "url" => url, "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let(:id) do - { - id: Digest::MD5.hexdigest(previous_menu.first["url"]) - } - end - - it_behaves_like "forbids disabled feature" - - it "returns http success" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it "updates the menu entry" do - action - - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - expect(items).to be_a(Array) - expect(items.count).to eq(1) - expect(items.first).to eq(attributes) - end - - context "when updating a non existing menu" do - let(:previous_menu) do - [{ "url" => "/another-menu", "position" => 10 }] - end - - it "creates a new item" do - action - items = AwesomeConfig.find_by(organization: organization, var: menu_name).value - - expect(items).to be_a(Array) - expect(items.count).to eq(2) - end - end - - context "when invalid parameters" do - let(:label) { { en: "" } } - - it "returns error" do - action - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:ok) - end - - it "do not create the new menu entry" do - action - - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(previous_menu) - end - end - end - - describe "DELETE #destroys" do - let(:action) { delete :destroy, params: params } - let(:previous_menu) do - [{ "url" => url, "position" => 10 }] - end - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let(:params) do - { - id: Digest::MD5.hexdigest(previous_menu.first["url"]) - } - end - - it "returns ok" do - action - expect(flash[:notice]).not_to be_empty - expect(response).to have_http_status(:redirect) - end - - it_behaves_like "forbids disabled feature" - - it "destroy the task" do - action - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq([]) - end - - context "when invalid parameters" do - let(:params) do - { - id: "nonsense" - } - end - - it "returns error" do - expect { action }.to raise_error(ActiveRecord::RecordNotFound) - expect(AwesomeConfig.find_by(organization: organization, var: menu_name).value).to eq(previous_menu) - end - end - end - end - end -end diff --git a/spec/controllers/editor_images_controller_spec.rb b/spec/controllers/editor_images_controller_spec.rb deleted file mode 100644 index fb0c828..0000000 --- a/spec/controllers/editor_images_controller_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe EditorImagesController, type: :controller do - routes { Decidim::DecidimAwesome::Engine.routes } - - let(:user) { create(:user, :confirmed, :admin, organization: organization) } - let(:organization) { create(:organization) } - let(:config) do - { - allow_images_in_proposals: in_proposals, - allow_images_in_small_editor: in_small, - allow_images_in_full_editor: in_full, - allow_images_in_markdown_editor: in_markdown - } - end - let(:in_proposals) { true } - let(:in_small) { true } - let(:in_full) { true } - let(:in_markdown) { true } - let(:params) do - { - image: image, - path: "/somepath" - } - end - let(:image) do - Rack::Test::UploadedFile.new( - Decidim::Dev.test_file("city.jpeg", "image/jpeg"), - "image/jpeg" - ) - end - - before do - allow(controller).to receive(:awesome_config).and_return(config) - request.env["decidim.current_organization"] = user.organization - sign_in user, scope: :user - end - - shared_examples "uploads image" do - context "when everything is ok" do - it "redirects as success success" do - post :create, params: params - expect(response).to have_http_status(:success) - end - end - - context "when there's no file" do - # TODO: remove nil when diching 0.26 support - let(:image) { legacy_version? ? nil : upload_test_file(Decidim::Dev.test_file("invalid.jpeg", "image/jpeg")) } - - it "returns failure" do - post :create, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - end - end - - describe "POST #create" do - include_examples "uploads image" - - context "when all config vars are false" do - let(:in_proposals) { false } - let(:in_small) { false } - let(:in_full) { false } - let(:in_markdown) { false } - - it "returns no permissions" do - post :create, params: params - expect(response).to have_http_status(:success) - end - end - end - - context "when user is not admin" do - let(:user) { create(:user, :confirmed, organization: organization) } - - include_examples "uploads image" - - context "when all config vars are false" do - let(:in_proposals) { false } - let(:in_small) { false } - let(:in_full) { false } - let(:in_markdown) { false } - - it "returns no permissions" do - post :create, params: params - expect(response).to have_http_status(:unprocessable_entity) - end - end - end - end -end diff --git a/spec/controllers/map_controller_spec.rb b/spec/controllers/map_controller_spec.rb deleted file mode 100644 index f59bdea..0000000 --- a/spec/controllers/map_controller_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/controller_examples" - -module Decidim::DecidimAwesome - module MapComponent - describe MapController, type: :controller do - routes { Decidim::DecidimAwesome::MapComponent::Engine.routes } - - let(:user) { create(:user, :confirmed, organization: component.organization) } - let(:component) { create(:map_component) } - - before do - request.env["decidim.current_organization"] = component.organization - request.env["decidim.current_participatory_space"] = component.participatory_space - request.env["decidim.current_component"] = component - end - - it_behaves_like "a blank component", Decidim::DecidimAwesome::MapComponent::AdminEngine - - describe "GET show" do - context "when everything is ok" do - it "renders the show page" do - get :show - expect(response).to have_http_status(:ok) - expect(subject).to render_template(:show) - end - end - - context "when no geocoder is available" do - before do - allow(Decidim).to receive(:maps).and_return(nil) - # TODO: remove when 0.22 is diched - allow(Decidim).to receive(:geocoder).and_return(nil) - end - - it "renders error page" do - get :show - expect(response).to have_http_status(:ok) - expect(subject).to render_template(:error) - end - end - end - - describe "map_components" do - let(:geocoding_enabled) { true } - let!(:meetings) { create(:component, participatory_space: component.participatory_space, manifest_name: :meetings) } - let!(:proposals) { create(:component, participatory_space: component.participatory_space, manifest_name: :proposals, settings: { geocoding_enabled: geocoding_enabled }) } - let!(:other) { create(:component, participatory_space: component.participatory_space, manifest_name: :dummy) } - - let(:components) do - [meetings, proposals] - end - - it "returns all allowed components" do - expect(subject.send(:map_components).map(&:id)).to include(meetings.id, proposals.id) - expect(subject.send(:map_components).map(&:id)).not_to include(other.id) - end - - context "when a component is not published" do - let!(:meetings) { create(:component, :unpublished, participatory_space: component.participatory_space, manifest_name: :meetings) } - - it "returns all published components" do - expect(subject.send(:map_components).map(&:id)).to include(proposals.id) - expect(subject.send(:map_components).map(&:id)).not_to include(other.id, meetings.id) - end - end - - context "when a component is not geolocated" do - let(:geocoding_enabled) { false } - - it "returns all geolocated components" do - expect(subject.send(:map_components).map(&:id)).to include(meetings.id) - expect(subject.send(:map_components).map(&:id)).not_to include(other.id, proposals.id) - end - end - end - end - end -end diff --git a/spec/controllers/proposals_controller_spec.rb b/spec/controllers/proposals_controller_spec.rb deleted file mode 100644 index af57bf2..0000000 --- a/spec/controllers/proposals_controller_spec.rb +++ /dev/null @@ -1,372 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals - describe ProposalsController, type: :controller do - routes { Decidim::Proposals::Engine.routes } - - let(:organization) { participatory_space.organization } - let(:participatory_space) { component.participatory_space } - let(:component) { create(:proposal_component, :with_votes_enabled, settings: settings) } - let!(:proposal1) { create(:proposal, title: { en: "m middle", ca: "à 3", "machine_translations" => { es: "a primero" } }, component: component) } - let!(:proposal2) { create(:proposal, title: { en: "z last", ca: "A 2", "machine_translations" => { es: "z último" } }, component: component) } - let!(:proposal3) { create(:proposal, title: { en: "a first", ca: "a 1", "machine_translations" => { es: "m medio" } }, component: component) } - let(:user) { create(:user, :confirmed, organization: component.organization) } - let!(:vote1) { create(:proposal_vote, proposal: proposal2, author: user) } - let!(:vote2) { create(:proposal_vote, proposal: proposal3, author: user) } - - let(:params) do - { - component_id: component.id - } - end - let(:settings) do - { - default_sort_order: default_order - } - end - - let(:default_order) { "default" } - - let(:additional_sortings) { [:supported_first, :supported_last, :az, :za] } - let(:config_defaults) do - { - additional_proposal_sortings: additional_sortings - } - end - let!(:awesome_config) { nil } - let!(:awesome_constraint) { nil } - let(:skip_collation_for) { "" } - - before do - # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(Decidim::DecidimAwesome::Config).to receive(:defaults).and_return(config_defaults) - allow_any_instance_of(Decidim::DecidimAwesome).to receive(:additional_proposal_sortings).and_return(additional_sortings) - allow_any_instance_of(ActionController::TestRequest).to receive(:url).and_return("/processes/#{participatory_space.slug}/proposals") - allow(Decidim::DecidimAwesome).to receive(:collation_for).and_call_original - allow(Decidim::DecidimAwesome).to receive(:collation_for).with(skip_collation_for).and_return(nil) - # rubocop:enable RSpec/AnyInstance - request.env["decidim.current_organization"] = organization - request.env["decidim.current_participatory_space"] = participatory_space - request.env["decidim.current_component"] = component - sign_in user - end - - describe "GET index" do - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent supported_first supported_last az za most_voted most_endorsed most_commented most_followed with_more_authors)) - expect(controller.send(:collation)).to eq('COLLATE "en-x-icu"') - end - - context "when collation is not found" do - let(:skip_collation_for) { :en } - - it "has order filters" do - get :index, params: params - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent supported_first supported_last az za most_voted most_endorsed most_commented most_followed with_more_authors)) - expect(controller.send(:collation)).to be_blank - end - end - - context "when no additional_sortings" do - let(:additional_sortings) { :disabled } - - it "has standard order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent most_voted most_endorsed most_commented most_followed with_more_authors)) - end - end - - context "when some additional_sortings" do - let(:additional_sortings) { [:az, :supported_last] } - - it "has standard order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az supported_last most_voted most_endorsed most_commented most_followed with_more_authors)) - end - end - - context "when unsupported additional_sortings" do - let(:additional_sortings) { [:baz, :az] } - - it "has standard order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az most_voted most_endorsed most_commented most_followed with_more_authors)) - end - end - - context "when awesome config exists" do - let!(:awesome_config) { create :awesome_config, organization: organization, var: :additional_proposal_sortings, value: additional_sortings } - - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent supported_first supported_last az za most_voted most_endorsed most_commented most_followed with_more_authors)) - end - - context "when customized" do - let(:additional_sortings) { [:az, :za] } - - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az za most_voted most_endorsed most_commented most_followed with_more_authors)) - end - - context "when constrained" do - let!(:awesome_constraint) { create(:config_constraint, awesome_config: awesome_config, settings: { "participatory_space_manifest" => "participatory_processes" }) } - - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az za most_voted most_endorsed most_commented most_followed with_more_authors)) - end - end - end - end - - context "when az order" do - let(:params) do - { - component_id: component.id, - order: "az" - } - end - - it "orders by az" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal3, proposal1, proposal2]) - end - - context "when other locale" do - let(:params) do - { - component_id: component.id, - order: "az", - locale: "ca" - } - end - - it "orders by az" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal3, proposal2, proposal1]) - end - end - - context "when machine_translations" do - let(:params) do - { - component_id: component.id, - order: "az", - locale: "es" - } - end - - it "orders by az" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal1, proposal3, proposal2]) - end - - context "and machine_translations are missing" do - let!(:proposal1) { create(:proposal, title: { en: "m middle", ca: "z últim" }, component: component) } - let!(:proposal2) { create(:proposal, title: { en: "z last", ca: "m mig" }, component: component) } - let!(:proposal3) { create(:proposal, title: { en: "a first", ca: "a primer" }, component: component) } - - it "orders by az as per default locale" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal3, proposal1, proposal2]) - end - end - end - end - - context "when za order" do - let(:params) do - { - component_id: component.id, - order: "za" - } - end - - it "orders by za" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal2, proposal1, proposal3]) - end - - context "when other locale" do - let(:params) do - { - component_id: component.id, - order: "za", - locale: "ca" - } - end - - it "orders by za" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal1, proposal2, proposal3]) - end - end - - context "when machine_translations" do - let(:params) do - { - component_id: component.id, - order: "za", - locale: "es" - } - end - - it "orders by za" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal2, proposal3, proposal1]) - end - - context "and machine_translations are missing" do - let!(:proposal1) { create(:proposal, title: { en: "m middle", ca: "z últim" }, component: component) } - let!(:proposal2) { create(:proposal, title: { en: "z last", ca: "m mig" }, component: component) } - let!(:proposal3) { create(:proposal, title: { en: "a first", ca: "a primer" }, component: component) } - - it "orders by za as per default locale" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal2, proposal1, proposal3]) - end - end - end - end - - context "when supported_first order" do - let(:params) do - { - component_id: component.id, - order: "supported_first" - } - end - - it "orders by supported_first" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal2, proposal3, proposal1]) - end - end - - context "when supported_last order" do - let(:params) do - { - component_id: component.id, - order: "supported_last" - } - end - - it "orders by supported_last" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal1, proposal2, proposal3]) - end - end - - context "when no votes enabled" do - let(:component) { create(:proposal_component, :with_votes_disabled) } - - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az za most_endorsed most_commented most_followed with_more_authors)) - end - end - - context "when no current_user" do - before do - allow(controller).to receive(:current_user).and_return(nil) - end - - it "has order filters" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(controller.helpers.available_orders).to eq(%w(random recent az za most_voted most_endorsed most_commented most_followed with_more_authors)) - end - end - - context "when order in session" do - before do - session[:order] = "supported_first" - end - - it "orders by supported_first" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal2, proposal3, proposal1]) - end - - context "when order is nonsense" do - let(:default_order) { "az" } - - before do - session[:order] = "nonsense" - end - - it "orders by default" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal3, proposal1, proposal2]) - end - end - end - - context "when order in params" do - let(:params) do - { - component_id: component.id, - order: "supported_last" - } - end - - it "orders by supported_last" do - get :index, params: params - - expect(response).to have_http_status(:ok) - expect(assigns(:proposals).to_a).to eq([proposal1, proposal2, proposal3]) - - get :index, params: params.except(:order) - expect(assigns(:proposals).to_a).to eq([proposal1, proposal2, proposal3]) - end - end - end - end -end diff --git a/spec/controllers/proposals_votes_controller_spec.rb b/spec/controllers/proposals_votes_controller_spec.rb deleted file mode 100644 index b803315..0000000 --- a/spec/controllers/proposals_votes_controller_spec.rb +++ /dev/null @@ -1,163 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals - describe ProposalVotesController, type: :controller do - routes { Decidim::Proposals::Engine.routes } - - let(:proposal) { create(:proposal, component: component) } - let(:user) { create(:user, :confirmed, organization: component.organization) } - - let(:params) do - { - proposal_id: proposal.id, - component_id: component.id - } - end - - let(:manifest) { nil } - let(:valid_manifest) { Decidim::DecidimAwesome.voting_registry.find(:voting_cards) } - - before do - allow(controller).to receive(:awesome_voting_manifest_for).and_return(manifest) - request.env["decidim.current_organization"] = component.organization - request.env["decidim.current_participatory_space"] = component.participatory_space - request.env["decidim.current_component"] = component - sign_in user - end - - shared_examples "can vote" do - it "allows voting" do - expect do - post :create, format: :js, params: params - end.to change(ProposalVote, :count).by(1) - - expect(ProposalVote.last.author).to eq(user) - expect(ProposalVote.last.proposal).to eq(proposal) - end - end - - shared_examples "no vote permissions" do - it "doesn't allow voting" do - expect do - post :create, format: :js, params: params - end.not_to change(ProposalVote, :count) - - expect(flash[:alert]).not_to be_empty - expect(response).to have_http_status(:found) - end - end - - shared_examples "invalid weight" do - it "doesn't allow voting" do - expect do - post :create, format: :js, params: params - end.not_to change(ProposalVote, :count) - - expect(response).to have_http_status(:unprocessable_entity) - end - end - - shared_examples "destroy vote" do - it "deletes the vote" do - expect do - delete :destroy, format: :js, params: params - end.to change(ProposalVote, :count).by(-1) - - expect(ProposalVote.count).to eq(0) - end - end - - describe "POST create" do - context "with votes enabled" do - let(:component) do - create(:proposal_component, :with_votes_enabled, settings: settings) - end - let(:settings) do - { - voting_cards_show_abstain: abstain - } - end - let(:abstain) { true } - - it_behaves_like "can vote" - - context "when manifest" do - let(:manifest) { valid_manifest } - - it_behaves_like "invalid weight" - - context "and params include weight" do - let(:weight) { 1 } - let(:params) do - { - proposal_id: proposal.id, - component_id: component.id, - weight: weight - } - end - - it_behaves_like "can vote" - - context "and weight is invalid" do - let(:weight) { 4 } - - it_behaves_like "invalid weight" - end - - context "and weight is abstain" do - let(:weight) { 0 } - - it_behaves_like "can vote" - - context "and abstain is disabled" do - let(:abstain) { false } - - it_behaves_like "invalid weight" - end - end - end - end - end - - context "with votes disabled" do - let(:component) do - create(:proposal_component) - end - - it_behaves_like "no vote permissions" - end - - context "with votes enabled but votes blocked" do - let(:component) do - create(:proposal_component, :with_votes_blocked) - end - - it_behaves_like "no vote permissions" - end - end - - describe "DELETE destroy" do - before do - create(:proposal_vote, proposal: proposal, author: user) - end - - context "with vote limit enabled" do - let(:component) do - create(:proposal_component, :with_votes_enabled, :with_vote_limit) - end - - it_behaves_like "destroy vote" - end - - context "with vote limit disabled" do - let(:component) do - create(:proposal_component, :with_votes_enabled) - end - - it_behaves_like "destroy vote" - end - end - end -end diff --git a/spec/forms/admin/config_form_spec.rb b/spec/forms/admin/config_form_spec.rb deleted file mode 100644 index 06aea9a..0000000 --- a/spec/forms/admin/config_form_spec.rb +++ /dev/null @@ -1,214 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe ConfigForm do - subject { described_class.from_params(attributes) } - - let(:attributes) do - { - allow_images_in_full_editor: true, - allow_images_in_small_editor: true - } - end - - let(:custom_styles) do - { - foo: valid_css - } - end - let(:valid_css) { ".valid_css {background: red;}" } - let(:invalid_css) { "invalid_css {background: ;}" } - let(:custom_fields) do - { - foo: valid_fields - } - end - let(:valid_fields) { '[{"foo":"bar"}]' } - let(:invalid_fields) { '[{"foo":"bar"}]{"baz":"zet"}' } - - let(:validate_title_min_length) { 15 } - let(:validate_title_max_caps_percent) { 25 } - let(:validate_title_max_marks_together) { 2 } - let(:validate_title_start_with_caps) { true } - let(:validate_body_min_length) { 15 } - let(:validate_body_max_caps_percent) { 25 } - let(:validate_body_max_marks_together) { 2 } - let(:validate_body_start_with_caps) { true } - - context "when everything is OK" do - it { is_expected.to be_valid } - end - - describe "custom styles" do - let(:attributes) do - { - scoped_styles: custom_styles - } - end - - it { is_expected.to be_valid } - - context "and invalid CSS" do - let(:custom_styles) do - { - foo: invalid_css - } - end - - it { is_expected.to be_invalid } - end - end - - describe "proposal custom fields" do - let(:attributes) do - { - proposal_custom_fields: custom_fields - } - end - - it { is_expected.to be_valid } - - context "and invalid JSON" do - let(:custom_fields) do - { - foo: invalid_fields - } - end - - it { is_expected.to be_invalid } - end - - context "and sending labels with html" do - let(:valid_fields) { '[{"label":"

Santana

"}]' } - - it "sanitize labels from html" do - expect(subject.proposal_custom_fields[:foo]).to include("Santana") - expect(subject.proposal_custom_fields[:foo]).not_to include("

Santana

") - end - end - end - - describe "validators" do - let(:attributes) do - { - validate_title_min_length: validate_title_min_length, - validate_title_max_caps_percent: validate_title_max_caps_percent, - validate_title_max_marks_together: validate_title_max_marks_together, - validate_title_start_with_caps: validate_title_start_with_caps, - validate_body_min_length: validate_body_min_length, - validate_body_max_caps_percent: validate_body_max_caps_percent, - validate_body_max_marks_together: validate_body_max_marks_together, - validate_body_start_with_caps: validate_body_start_with_caps - } - end - - it { is_expected.to be_valid } - - context "and title start with caps is false" do - let(:validate_title_start_with_caps) { false } - - it { is_expected.to be_valid } - end - - context "and title min length is empty" do - let(:validate_title_min_length) { nil } - - it { is_expected.to be_invalid } - end - - context "and title min length is zero" do - let(:validate_title_min_length) { 0 } - - it { is_expected.to be_invalid } - end - - context "and title min length greater than 100" do - let(:validate_title_min_length) { 101 } - - it { is_expected.to be_invalid } - end - - context "and body min length is empty" do - let(:validate_body_min_length) { nil } - - it { is_expected.to be_invalid } - end - - context "and body min length is zero" do - let(:validate_body_min_length) { 0 } - - it { is_expected.to be_valid } - end - - context "and title max caps percent empty" do - let(:validate_title_max_caps_percent) { nil } - - it { is_expected.to be_invalid } - end - - context "and title max caps percent is zero" do - let(:validate_title_max_caps_percent) { 0 } - - it { is_expected.to be_valid } - end - - context "and title max caps percent is bigger than 100" do - let(:validate_title_max_caps_percent) { 101 } - - it { is_expected.to be_invalid } - end - - context "and body start with caps is false" do - let(:validate_body_start_with_caps) { false } - - it { is_expected.to be_valid } - end - - context "and body max caps percent empty" do - let(:validate_body_max_caps_percent) { nil } - - it { is_expected.to be_invalid } - end - - context "and body max caps percent is zero" do - let(:validate_body_max_caps_percent) { 0 } - - it { is_expected.to be_valid } - end - - context "and body max caps percent is bigger than 100" do - let(:validate_body_max_caps_percent) { 101 } - - it { is_expected.to be_invalid } - end - - context "and title max marks together is empty" do - let(:validate_title_max_marks_together) { nil } - - it { is_expected.to be_invalid } - end - - context "and title max marks together is zero" do - let(:validate_title_max_marks_together) { 0 } - - it { is_expected.to be_invalid } - end - - context "and body max marks together is empty" do - let(:validate_body_max_marks_together) { nil } - - it { is_expected.to be_invalid } - end - - context "and body max marks together is zero" do - let(:validate_body_max_marks_together) { 0 } - - it { is_expected.to be_invalid } - end - end - end - end -end diff --git a/spec/forms/admin/constraint_form_spec.rb b/spec/forms/admin/constraint_form_spec.rb deleted file mode 100644 index d81efcb..0000000 --- a/spec/forms/admin/constraint_form_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe ConstraintForm do - subject { described_class.from_params(attributes) } - - let(:attributes) do - { - participatory_space_manifest: "some-manifest" - } - end - - context "when everything is OK" do - it { is_expected.to be_valid } - end - - context "when component manifest specified" do - let(:attributes) do - { - component_manifest: "some-manifest" - } - end - - it { is_expected.to be_valid } - - context "and component_id is specified" do - let(:attributes) do - { - component_manifest: "some-manifest", - component_id: 123 - } - end - - it { is_expected.to be_invalid } - end - - context "and space manifest is not a participatory space" do - let(:attributes) do - { - participatory_space_manifest: "system", - component_manifest: "some-manifest" - } - end - - it { is_expected.to be_invalid } - end - end - - context "when component ID specified" do - let(:attributes) do - { - component_id: 123 - } - end - - it { is_expected.to be_valid } - - context "and component manifest is specified" do - let(:attributes) do - { - component_manifest: "some-manifest", - component_id: 123 - } - end - - it { is_expected.to be_invalid } - end - end - end - end -end diff --git a/spec/forms/admin/custom_redirect_form_spec.rb b/spec/forms/admin/custom_redirect_form_spec.rb deleted file mode 100644 index aee39b7..0000000 --- a/spec/forms/admin/custom_redirect_form_spec.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe CustomRedirectForm do - subject { described_class.from_params(attributes).with_context(current_organization: organization) } - - let(:organization) { create :organization } - let(:attributes) do - { - origin: origin, - destination: destination, - active: active, - pass_query: pass_query - } - end - - let(:origin) { "/some-path" } - let(:destination) { "/some-destination" } - let(:active) { true } - let(:pass_query) { true } - - context "when everything is OK" do - it { is_expected.to be_valid } - - it "returns normalized values" do - expect(subject.to_params).to eq([origin, { destination: destination, active: active, pass_query: pass_query }]) - end - end - - context "when origin is empty" do - let(:origin) { "" } - - it { is_expected.to be_invalid } - - context "and is only spaces" do - let(:origin) { " " } - - it { is_expected.to be_invalid } - end - end - - context "when destination empty" do - let(:destination) { "" } - - it { is_expected.to be_invalid } - - context "and is only spaces" do - let(:destination) { " " } - - it { is_expected.to be_invalid } - end - end - - context "when origin is malformed" do - let(:origin) { " some-Origin " } - - it { is_expected.to be_valid } - - it "sanitizes origin" do - expect(subject.to_params[0]).to eq("/some-Origin") - end - - context "and origin has organization host" do - let(:origin) { "http://#{organization.host}/some-Origin " } - - it "strips host" do - expect(subject.to_params[0]).to eq("/some-Origin") - end - end - end - - context "when destination is malformed" do - let(:destination) { " some-destInation " } - - it { is_expected.to be_valid } - - it "sanitizes destination" do - expect(subject.to_params[1][:destination]).to eq("/some-destInation") - end - - context "and destination has organization host" do - let(:destination) { "http://#{organization.host}/some-destination " } - - it "maintains host" do - expect(subject.to_params[1][:destination]).to eq("http://#{organization.host}/some-destination") - end - end - end - - context "when origin and destination are the same" do - let(:destination) { "http://#{organization.host}#{origin} " } - - it { is_expected.to be_invalid } - end - - context "when origin and destination are case sensitive" do - let(:origin) { "/Some-Origin-Path".downcase } - let(:destination) { "http://#{organization.host}/Some-Origin-Path".downcase } - - it "compares origin and destination without considering case" do - expect(origin).not_to eq("/Some-Origin-Path") - expect(destination).not_to eq("http://#{organization.host}/Some-Origin-Path") - end - end - end - end -end diff --git a/spec/forms/admin/menu_form_spec.rb b/spec/forms/admin/menu_form_spec.rb deleted file mode 100644 index 47fb6b6..0000000 --- a/spec/forms/admin/menu_form_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - module Admin - describe MenuForm do - subject { described_class.from_params(attributes).with_context(current_organization: organization) } - - let(:organization) { create :organization } - let(:url) { "/some-path" } - let(:position) { 2 } - let(:target) { "_blank" } - let(:visibility) { "hidden" } - let(:attributes) do - { - raw_label: label, - url: url, - position: position, - target: target, - visibility: visibility - } - end - - if legacy_version? - let(:label) do - { - en: "Menu english", - ca: "Menu catalan" - } - end - else - let(:label) do - { - "en" => "Menu english", - "ca" => "Menu catalan" - } - end - end - - context "when everything is OK" do - it { is_expected.to be_valid } - - it "returns normalized values" do - expect(subject.to_params).to eq(label: label, url: url, position: position, target: target, visibility: visibility) - end - end - - context "when label is not a hash" do - let(:label) { nil } - - it { is_expected.to be_invalid } - end - - context "when url is empty" do - let(:url) { "" } - - it { is_expected.to be_invalid } - end - - context "when position is not numeric" do - let(:position) { "hacker!" } - - it { is_expected.to be_invalid } - end - - context "when target is not included in options" do - let(:target) { "hacker!" } - - it { is_expected.to be_invalid } - end - - context "when visibility is not included in options" do - let(:visibility) { "hacker!" } - - it { is_expected.to be_invalid } - end - end - end -end diff --git a/spec/forms/editor_image_form_spec.rb b/spec/forms/editor_image_form_spec.rb deleted file mode 100644 index bdd82df..0000000 --- a/spec/forms/editor_image_form_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe EditorImageForm do - subject { described_class.from_params(attributes).with_context(context) } - - let(:user) { create :user } - let(:organization) { user.organization } - - let(:attributes) do - { - file: file, - path: "/somepath", - author_id: user.id - } - end - let(:context) do - { - current_organization: organization, - current_user: user - } - end - let(:file) { Decidim::Dev.test_file("city.jpeg", "image/jpeg") } - - context "when everything is OK" do - it { is_expected.to be_valid } - end - - context "when everything no image" do - let(:file) { nil } - - it { is_expected.not_to be_valid } - end - end -end diff --git a/spec/forms/proposal_wizard_create_step_form_spec.rb b/spec/forms/proposal_wizard_create_step_form_spec.rb deleted file mode 100644 index ca8e29b..0000000 --- a/spec/forms/proposal_wizard_create_step_form_spec.rb +++ /dev/null @@ -1,265 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals - describe ProposalWizardCreateStepForm do - subject { form } - - let(:params) do - { - title: title, - body: body, - body_template: body_template - } - end - - let(:organization) { create(:organization, available_locales: [:en]) } - let(:participatory_space) { create(:participatory_process, :with_steps, organization: organization) } - let(:component) { create(:proposal_component, participatory_space: participatory_space) } - let(:title) { "More sidewalks and less roads" } - let(:body) { nil } - let(:body_template) { nil } - let(:author) { create(:user, organization: organization) } - - let(:form) do - described_class.from_params(params).with_context( - current_component: component, - current_organization: component.organization, - current_participatory_space: participatory_space - ) - end - - let(:data) { '{"type":"text","label":"Full Name","subtype":"text","className":"form-control","name":"text-1476748004559"}' } - let(:custom_fields) do - { - "foo" => "[#{data}]" - } - end - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_foo } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - let(:slug) { participatory_space.slug } - - context "when is scoped under custom fields" do - it { is_expected.to be_valid } - end - - context "when not scoped under custom fields" do - let(:slug) { "another-slug" } - - context "and body is not present" do - it { is_expected.to be_invalid } - end - - context "and body is invalid" do - let(:body) { "aa" } - - it { is_expected.to be_invalid } - end - end - - context "when there's a body template set" do - let(:body_template) { "This is the template" } - - context "when is scoped under custom fields" do - it { is_expected.to be_valid } - - context "when the template and the body are the same" do - let(:body) { body_template } - - it { is_expected.to be_valid } - end - end - - context "when not scoped under custom fields" do - let(:slug) { "another-slug" } - - it { is_expected.to be_invalid } - - context "when the template and the body are the same" do - let(:body) { body_template } - - it { is_expected.to be_invalid } - end - end - end - - context "when is a participatory text" do - let(:component) { create(:proposal_component, :with_participatory_texts_enabled, participatory_space: participatory_space) } - - it { is_expected.to be_invalid } - end - - context "when the body exceeds the permited length" do - let(:component) { create(:proposal_component, :with_proposal_length, participatory_space: participatory_space, proposal_length: allowed_length) } - let(:allowed_length) { 15 } - let(:body) { "A body longer than the permitted" } - - context "when not scoped under custom fields" do - let(:slug) { "another-slug" } - - it { is_expected.to be_invalid } - end - - context "when is scoped under custom fields" do - it { is_expected.to be_valid } - end - end - - shared_examples "starts with caps" do |prop| - let!(:config) { create :awesome_config, organization: organization, var: "validate_#{prop}_start_with_caps", value: enabled } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - - let(:enabled) { false } - let(prop.to_sym) { "í don't start with caps" } - - it { is_expected.to be_valid } - - context "when scoped under different context" do - let(:slug) { "another-slug" } - - it { is_expected.to be_invalid } - - context "when starts with caps" do - let(prop.to_sym) { "Í start with caps" } - - it { is_expected.to be_valid } - end - end - - context "when enabled" do - let(:enabled) { true } - - it { is_expected.to be_invalid } - - context "when starts with caps" do - let(prop.to_sym) { "Í start with caps" } - - it { is_expected.to be_valid } - end - end - end - - shared_examples "minimum length" do |prop| - let!(:config) { create :awesome_config, organization: organization, var: "validate_#{prop}_min_length", value: min_length } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - - let(:min_length) { 10 } - let(prop.to_sym) { "I am 10 yo" } - - it { is_expected.to be_valid } - - context "when scoped under different context" do - let(:slug) { "another-slug" } - - it { is_expected.to be_invalid } - - context "when has more than 15 chars" do - let(prop.to_sym) { "I am 17 years old" } - - it { is_expected.to be_valid } - end - end - - context "when less than allowed" do - let(:min_length) { 11 } - - it { is_expected.to be_invalid } - end - - context "when min_length is zero" do - let(:min_length) { 0 } - let(prop.to_sym) { "" } - - if prop == :body - it { is_expected.to be_valid } - else - it { is_expected.to be_invalid } - end - end - end - - shared_examples "max caps percent" do |prop| - let!(:config) { create :awesome_config, organization: organization, var: "validate_#{prop}_max_caps_percent", value: percent } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - - let(:percent) { 90 } - let(prop.to_sym) { "Í ÁM A SÈMI-CÁPS text" } - - it { is_expected.to be_valid } - - shared_examples "invalid percentage" do |per| - it "error message returns percentage" do - expect(form).to be_invalid - expect(form.errors.messages.values.flatten.first).to include("over #{per}% of the text") - end - end - - context "when scoped under different context" do - let(:slug) { "another-slug" } - - it_behaves_like "invalid percentage", 25 - - context "when has less than 25% caps" do - let(prop.to_sym) { "Í only have some CÁPS" } - - it { is_expected.to be_valid } - end - end - - context "when less than allowed" do - let(:percent) { 11 } - - it_behaves_like "invalid percentage", 11 - end - end - - shared_examples "max marks together" do |prop| - let!(:config) { create :awesome_config, organization: organization, var: "validate_#{prop}_max_marks_together", value: max_marks } - let!(:constraint) { create(:config_constraint, awesome_config: config, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - - let(:max_marks) { 5 } - let(prop.to_sym) { "Am I a little bit noisy??!!!" } - - it { is_expected.to be_valid } - - context "when scoped under different context" do - let(:slug) { "another-slug" } - - it { is_expected.to be_invalid } - - context "when has only 1 mark" do - let(prop.to_sym) { "I am not noisy!" } - - it { is_expected.to be_valid } - end - - context "when has 2 marks" do - let(prop.to_sym) { "I am not noisy!?" } - - it { is_expected.to be_invalid } - end - end - - context "when less than allowed" do - let(:max_marks) { 4 } - - it { is_expected.to be_invalid } - end - end - - describe "etiquette validations" do - let(:body) { "A body longer than the permitted" } - - it_behaves_like "minimum length", :title - it_behaves_like "minimum length", :body - it_behaves_like "starts with caps", :title - it_behaves_like "starts with caps", :body - it_behaves_like "max caps percent", :title - it_behaves_like "max caps percent", :body - it_behaves_like "max marks together", :title - it_behaves_like "max marks together", :body - end - end -end diff --git a/spec/helpers/awesome_helpers_spec.rb b/spec/helpers/awesome_helpers_spec.rb index a77b595..1f8cb82 100644 --- a/spec/helpers/awesome_helpers_spec.rb +++ b/spec/helpers/awesome_helpers_spec.rb @@ -44,11 +44,6 @@ module Decidim::DecidimAwesome end end - it "returns a voting manifest" do - expect(helper.awesome_voting_manifest_for(component)).to be_a(VotingManifest) - expect(helper.awesome_voting_manifest_for(component).name).to eq(manifest) - end - context "when no manifest" do let(:manifest) { nil } diff --git a/spec/helpers/map_helper_spec.rb b/spec/helpers/map_helper_spec.rb deleted file mode 100644 index cc4b6bb..0000000 --- a/spec/helpers/map_helper_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe MapHelper, type: :helper do - let(:snippets) { defined?(Decidim::Snippets) ? Decidim::Snippets.new : nil } - let(:current_participatory_space) { create(:participatory_process) } - let(:current_component) do - create(:component, participatory_space: current_participatory_space, manifest_name: "awesome_map") - end - let(:components) do - [ - create(:component, participatory_space: current_participatory_space, manifest_name: "meetings"), - create(:component, participatory_space: current_participatory_space, manifest_name: "proposals") - ] - end - let!(:category) { create(:category, participatory_space: current_participatory_space) } - let!(:subcategory) { create(:category, parent: category) } - let(:categories) do - [{ - id: category.id, - name: category.name["en"], - parent: nil, - color: "#ffaa33" - }, { - id: subcategory.id, - name: subcategory.name["en"], - parent: category.id, - color: "#ffaa33" - }] - end - - before do - allow(helper).to receive(:current_participatory_space).and_return(current_participatory_space) - allow(helper).to receive(:current_organization).and_return(current_participatory_space.organization) - allow(helper).to receive(:current_component).and_return(current_component) - allow(helper).to receive(:snippets).and_return(snippets) - allow(helper).to receive(:translated_attribute) do |string| - string["en"] - end - end - - describe "awesome_map_for" do - it "returns a map tag" do - body = -> { "
html body
".html_safe } - expect(helper.awesome_map_for(components, &body)).to include("
html body
") - expect(helper.awesome_map_for(components, &body)).to include("data-components=") - expect(helper.awesome_map_for(components, &body)).to include('data-collapsed="false"') - end - end - - describe "current_categories" do - before do - allow(helper).to receive(:hsv_to_rgb).and_return([255, 0xAA, 0x33]) - end - - it "return formatted categories" do - expect(helper.current_categories(current_participatory_space.categories)).to eq(categories) - end - end - - describe "hsv_to_rgb" do - it "converst hsv to rgb" do - expect(helper.send(:hsv_to_rgb, 0.3, 0.5, 0.7)).to eq([107, 179, 89]) - expect(helper.send(:hsv_to_rgb, 0, 1, 1)).to eq([256, 0, 0]) - expect(helper.send(:hsv_to_rgb, 5 / 6r, 0, 1)).to eq([256, 256, 256]) - expect(helper.send(:hsv_to_rgb, 4 / 6r, 1, 0)).to eq([0, 0, 0]) - expect(helper.send(:hsv_to_rgb, 3 / 6r, 0.4, 0.2)).to eq([30, 51, 51]) - expect(helper.send(:hsv_to_rgb, 2 / 6r, 0.5, 0.4)).to eq([51, 102, 51]) - expect(helper.send(:hsv_to_rgb, 1 / 6r, 0.5, 0.1)).to eq([25, 25, 12]) - end - end - end -end diff --git a/spec/jobs/export_admin_actions_job_spec.rb b/spec/jobs/export_admin_actions_job_spec.rb deleted file mode 100644 index 7cb4dfa..0000000 --- a/spec/jobs/export_admin_actions_job_spec.rb +++ /dev/null @@ -1,159 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe ExportAdminActionsJob do - subject { described_class } - let(:organization) { create :organization } - let(:external_organization) { create :organization } - let!(:user) { create :user, :admin, :confirmed, organization: organization } - let!(:manager) { create(:user, :user_manager, organization: organization, last_sign_in_at: 6.days.ago, created_at: 7.days.ago) } - let(:administrator) { create(:user, organization: organization, last_sign_in_at: 6.days.ago, created_at: 7.days.ago) } - let(:valuator) { create(:user, name: "Lorry", email: "test@example.org", organization: organization, created_at: 7.days.ago) } - let(:collaborator) { create(:user, organization: organization, created_at: 7.days.ago) } - let(:moderator) { create(:user, organization: organization, created_at: 7.days.ago) } - let!(:participatory_process_user_role1) { create(:participatory_process_user_role, user: administrator, role: "admin", created_at: 4.days.ago) } - let!(:participatory_process_user_role2) { create(:participatory_process_user_role, user: valuator, role: "valuator", created_at: 3.days.ago) } - let!(:participatory_process_user_role3) { create(:participatory_process_user_role, user: collaborator, role: "collaborator", created_at: 2.days.ago) } - let!(:participatory_process_user_role4) { create(:participatory_process_user_role, user: moderator, role: "moderator", created_at: 1.day.ago) } - let!(:assembly_user_role1) { create(:assembly_user_role, user: administrator, role: "admin", created_at: 4.days.ago) } - let!(:assembly_user_role2) { create(:assembly_user_role, user: valuator, role: "valuator", created_at: 3.days.ago) } - let!(:assembly_user_role3) { create(:assembly_user_role, user: collaborator, role: "collaborator", created_at: 2.days.ago) } - let!(:assembly_user_role4) { create(:assembly_user_role, user: moderator, role: "moderator", created_at: 1.day.ago) } - - let!(:external_administrator) { create(:user, organization: external_organization, last_sign_in_at: 6.days.ago, created_at: 7.days.ago) } - let!(:external_participatory_process_user_role1) { create(:participatory_process_user_role, user: external_administrator, role: "admin", created_at: 4.days.ago) } - - let(:collection_ids) { Decidim::DecidimAwesome::PaperTrailVersion.space_role_actions(organization).pluck(:id) } - let(:format) { "CSV" } - let(:ext) { "csv" } - - before do - # ensure papertrail has the same created_at date as the object being mocked - Decidim::DecidimAwesome::PaperTrailVersion.space_role_actions(organization).map { |v| v.update(created_at: v.item.created_at) } - end - - shared_examples "an export job" do - it "sends an email with the result of the export", versioning: true do - perform_enqueued_jobs do - subject.perform_now(user, format, collection_ids) - end - - email = last_email - expect(email.subject).to match(/Your export "admin_actions-#{Time.current.strftime("%Y-%m-%d")}-([0-9]+).#{ext}" is ready/) - expect(email.body.encoded).to match("Please find attached a zipped version of your export") - end - end - - it_behaves_like "an export job" - - it_behaves_like "an export job" do - let(:format) { "JSON" } - let(:ext) { "json" } - end - - it_behaves_like "an export job" do - let(:format) { "Excel" } - let(:ext) { "xlsx" } - end - - it "serializes the data", versioning: true do - expect(subject.new.send(:serialized_collection, collection_ids).count).to eq(8) - expect(subject.new.send(:serialized_collection, collection_ids).pluck(:user_email).uniq).to match_array([administrator.email, valuator.email, collaborator.email, moderator.email]) - end - - context "when external organization" do - let(:collection_ids) { Decidim::DecidimAwesome::PaperTrailVersion.space_role_actions(external_organization).pluck(:id) } - - it "serializes the data", versioning: true do - expect(subject.new.send(:serialized_collection, collection_ids).count).to eq(1) - expect(subject.new.send(:serialized_collection, collection_ids).pluck(:user_email).uniq).to match_array([external_administrator.email]) - end - end - - context "when filtered data" do - let(:collection_ids) { PaperTrailVersion.space_role_actions(organization).where(item_type: "Decidim::AssemblyUserRole").where("created_at > ?", 3.days.ago).pluck(:id) } - let(:result) do - [ - { - last_sign_in_at: "Never logged yet", - participatory_space_title: assembly_user_role4.assembly.title["en"], - participatory_space_type: "Assemblies", - role: "Moderator", - role_created_at: assembly_user_role4.created_at.strftime("%d/%m/%Y %H:%M"), - user_email: moderator.email, - user_name: moderator.name, - role_removed_at: "Currently active", - user_role_type: "Decidim::AssemblyUserRole" - }, - { - last_sign_in_at: "Never logged yet", - participatory_space_title: assembly_user_role3.assembly.title["en"], - participatory_space_type: "Assemblies", - role: "Collaborator", - role_created_at: assembly_user_role3.created_at.strftime("%d/%m/%Y %H:%M"), - user_email: collaborator.email, - user_name: collaborator.name, - role_removed_at: "Currently active", - user_role_type: "Decidim::AssemblyUserRole" - } - ] - end - - it "serializes the data", versioning: true do - expect(subject.new.send(:serialized_collection, collection_ids)).to eq(result) - end - end - - context "when export global admins" do - let(:collection_ids) { Decidim::DecidimAwesome::PaperTrailVersion.admin_role_actions.pluck(:id) } - - it_behaves_like "an export job" - - it_behaves_like "an export job" do - let(:format) { "JSON" } - let(:ext) { "json" } - end - - it_behaves_like "an export job" do - let(:format) { "Excel" } - let(:ext) { "xlsx" } - end - - context "when filtered data" do - let(:collection_ids) { PaperTrailVersion.admin_role_actions.where("created_at > ?", 3.days.ago).pluck(:id) } - let(:result) do - [ - { - last_sign_in_at: manager.last_sign_in_at.strftime("%d/%m/%Y %H:%M"), - participatory_space_title: "", - participatory_space_type: nil, - role: "User manager", - role_created_at: manager.created_at.strftime("%d/%m/%Y %H:%M"), - user_email: manager.email, - user_name: manager.name, - role_removed_at: "Currently active", - user_role_type: "Decidim::UserBaseEntity" - }, - { - last_sign_in_at: "Never logged yet", - participatory_space_title: "", - participatory_space_type: nil, - role: "Super admin", - role_created_at: user.created_at.strftime("%d/%m/%Y %H:%M"), - user_email: user.email, - user_name: user.name, - role_removed_at: "Currently active", - user_role_type: "Decidim::UserBaseEntity" - } - ] - end - - it "serializes the data", versioning: true do - expect(subject.new.send(:serialized_collection, collection_ids)).to eq(result) - end - end - end - end -end diff --git a/spec/jobs/migrate_legacy_images_job_spec.rb b/spec/jobs/migrate_legacy_images_job_spec.rb deleted file mode 100644 index 4048721..0000000 --- a/spec/jobs/migrate_legacy_images_job_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe MigrateLegacyImagesJob do - subject { described_class } - - let!(:organization) { create :organization } - let!(:another_organization) { create :organization } - let!(:user) { create :user, organization: organization } - let!(:new_image) { create :awesome_editor_image, organization: organization } - let!(:old_image) { create :awesome_editor_image, organization: organization, file: nil, image: "city.jpeg" } - let(:path) { "/uploads/decidim/decidim_awesome/editor_image/image/#{old_image.id}" } - let(:text) do - { "en" => body } - end - let(:body) { "" } - let(:logger) { Logger.new($stdout) } - - before do - FileUtils.mkdir_p "#{__dir__}/../decidim_dummy_app/public/#{path}" - FileUtils.cp_r Decidim::Dev.asset("city.jpeg"), "#{__dir__}/../decidim_dummy_app/public/#{path}/city.jpeg" - organization.welcome_notification_body = text - organization.save! - end - - after do - FileUtils.rm_r "#{__dir__}/../decidim_dummy_app/public/uploads", force: true - end - - it "sends an email with the result of the export" do - mappings = [] - expect(new_image.file.attached?).to be true - expect(old_image.file.attached?).to be false - expect(organization.welcome_notification_body["en"]).to include("#{path}/city.jpeg") - - subject.perform_now(organization.id, mappings, logger) - expect(new_image.reload.file.attached?).to be true - expect(old_image.reload.file.attached?).to be true - expect(organization.reload.welcome_notification_body["en"]).not_to include("#{path}/city.jpeg") - expect(organization.welcome_notification_body["en"]).to include(old_image.attached_uploader(:file).path) - end - end -end diff --git a/spec/lib/config_spec.rb b/spec/lib/config_spec.rb index 2c9dd92..7ea38ae 100644 --- a/spec/lib/config_spec.rb +++ b/spec/lib/config_spec.rb @@ -86,185 +86,5 @@ module Decidim::DecidimAwesome participatory_space_slug: participatory_process.slug ) end - - context "when some config is personalized" do - let(:custom_config) do - config.merge(allow_images_in_full_editor: true) - end - let!(:awesome_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: true } - - it "differs from the basic config" do - expect(subject.config).not_to eq(config) - end - - it "matches personalized config" do - expect(subject.config).to eq(custom_config) - end - - context "and some value is a hash" do - let(:settings) do - { - "chat_id" => "-1234", - :color => "red", - use_floating_button: true - } - end - let!(:awesome_config) { create :awesome_config, organization: organization, var: :intergram_for_public_settings, value: settings } - - it "returns the config normalized" do - expect(subject.config[:intergram_for_public_settings][:chat_id]).to eq("-1234") - expect(subject.config[:intergram_for_public_settings][:color]).to eq("red") - expect(subject.config[:intergram_for_public_settings][:require_login]).to be(true) - expect(subject.config[:intergram_for_public_settings][:use_floating_button]).to be(true) - end - end - end - - context "when some config is disabled" do - before do - subject.defaults = Decidim::DecidimAwesome.config.merge(allow_images_in_full_editor: :disabled) - # de-memoize - subject.instance_variable_set :@config, nil - end - - let!(:awesome_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: true } - - it "always defaults to false" do - expect(subject.config[:allow_images_in_full_editor]).to be(false) - end - end - - context "when there are constraints" do - let!(:awesome_config) { create :awesome_config, organization: organization, var: :allow_images_in_full_editor, value: true } - let!(:constraint1) { create :config_constraint, awesome_config: awesome_config, settings: settings1 } - let!(:constraint2) { create :config_constraint, awesome_config: awesome_config, settings: settings2 } - let(:settings1) do - { - participatory_space_manifest: "assemblies" - } - end - let(:settings2) do - { - participatory_space_manifest: manifest, - participatory_slug: slug, - component_id: id - } - end - let(:manifest) { participatory_process.manifest.name.to_s } - let(:slug) { participatory_process.slug } - let(:id) { nil } - let(:custom_config) do - config.merge(allow_images_in_full_editor: true) - end - - before do - subject.context = { - participatory_space_manifest: participatory_process.manifest.name.to_s, - participatory_slug: participatory_process.slug - } - end - - it "differs from the basic config" do - expect(subject.config).not_to eq(config) - end - - it "matches personalized config" do - expect(subject.config).to eq(custom_config) - end - - context "and no constraints matches context" do - let(:slug) { "another-slug" } - - it "matches basic config" do - expect(subject.config).to eq(config) - end - - it "differs from personalized config" do - expect(subject.config).not_to eq(custom_config) - end - end - end - - context "when there are subconfigs" do - let!(:awesome_config) { create :awesome_config, organization: organization, var: :scoped_styles, value: values } - let(:config_helper_foo) { create :awesome_config, organization: organization, var: :scoped_style_foo, value: nil } - let(:config_helper_bar) { create :awesome_config, organization: organization, var: :scoped_style_bar, value: nil } - let!(:constraint_foo) { create(:config_constraint, awesome_config: config_helper_foo, settings: settings_foo) } - let!(:constraint_bar) { create(:config_constraint, awesome_config: config_helper_bar, settings: settings_bar) } - let(:values) do - { - "foo" => "{ color: red; }", - "bar" => "{ color: blue; }" - } - end - let(:settings_foo) do - { - "participatory_space_manifest" => participatory_process.manifest.name.to_s, - "participatory_space_slug" => participatory_process.slug - } - end - let(:settings_bar) do - { - "participatory_space_manifest" => "assemblies" - } - end - let(:all_subconfigs) do - { - foo: config_helper_foo, - bar: config_helper_bar - } - end - let(:request) { double(url: "/processes/#{participatory_process.slug}") } - let(:subconfigs) { subject.sub_configs_for("scoped_style") } - let(:collected_values) { subject.collect_sub_configs_values("scoped_style") } - let(:unfiltered_collected_values) do - subject.collect_sub_configs_values("scoped_style") { true } - end - let(:additional_constraints) do - [double(settings: { "participatory_space_manifest" => "none" })] - end - - it "gathers subconfigs" do - expect(subconfigs).to eq(all_subconfigs) - expect(collected_values).to eq([]) - end - - it "filters subconfig values in the current context" do - subject.context_from_request(request) - expect(collected_values).to eq([values["foo"]]) - end - - it "can collect all subconfig values" do - subject.context_from_request(request) - expect(unfiltered_collected_values).to match_array(values.values) - end - - it "can dynamically add constraints" do - subject.inject_sub_config_constraints("scoped_style", "foo", additional_constraints) - expect(subconfigs[:foo].constraints).not_to include(additional_constraints.first) - expect(subconfigs[:foo].all_constraints).to include(additional_constraints.first) - end - - context "when several results" do - let(:settings_bar) do - { - "participatory_space_manifest" => participatory_process.manifest.name.to_s - } - end - - before do - subject.context_from_request(request) - end - - it "callects all matching values" do - expect(collected_values).to match_array(values.values) - end - - it "dynamically added constraints affectes evaluated subconfig values" do - subject.inject_sub_config_constraints("scoped_style", "bar", additional_constraints) - expect(collected_values).to eq([values["foo"]]) - end - end - end end end diff --git a/spec/lib/custom_fields_spec.rb b/spec/lib/custom_fields_spec.rb deleted file mode 100644 index d4da896..0000000 --- a/spec/lib/custom_fields_spec.rb +++ /dev/null @@ -1,298 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe CustomFields do - subject { described_class.new fields } - - let(:fields) do - [ - box1, - box2 - ] - end - let(:box1) { '[{"type":"text","required":true,"label":"Age","name":"age"}]' } - let(:box2) { '[{"type":"textarea","required":true,"label":"Birthday","name":"date"}]' } - let(:bare_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age" }, - { "type" => "text", "required" => true, "label" => "Birthday", "name" => "date" } - ] - end - let(:compatible_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age" }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["

I am a former text, written before definition of custom fields in this proposal.

"] } - ] - end - let(:compatible_text_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age" }, - { "type" => "textarea", "required" => true, "subtype" => "textarea", "name" => "date", "userData" => ["I am a former text, written before definition of custom fields in this proposal."] } - ] - end - let(:partial_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age" }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16"] } - ] - end - let(:html_json) do - [ - { "type" => "text", "required" => true, "label" => "Textarea", "name" => "textarea", "userData" => ["

I am Pi!

"] }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16"] } - ] - end - let(:array_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age", "userData" => ["44"] }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16", "1/12/1880"] } - ] - end - let(:partial_array_json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age" }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16", "1/12/1880"] } - ] - end - let(:json) do - [ - { "type" => "text", "required" => true, "label" => "Age", "name" => "age", "userData" => ["44"] }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16"] } - ] - end - let(:one_json) do - [ - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16"] } - ] - end - let(:utf8_json) do - [ - { "type" => "textarea", "required" => true, "label" => "Textarea", "name" => "textarea", "userData" => ["Test äöüéè👽"] } - ] - end - let(:header_json) do - [ - { "type" => "header", "label" => "Header", "subtype" => "h1" }, - { "type" => "textarea", "required" => true, "label" => "Birthday", "name" => "date", "userData" => ["1980-04-16"] } - ] - end - let(:xml) { '
Age
44
Birthday
16/4/1980
' } - - before do - subject.apply_xml xml - end - - it "joins everything in JSON format" do - expect(subject.to_json).to eq(json) - expect(subject.errors).to be_nil - end - - context "when xml is empty" do - let(:xml) { " \n " } - let(:box2) { '[{"type":"text","required":true,"label":"Birthday","name":"date"}]' } - - it "returns custom fields default values" do - expect(subject.to_json).to eq(bare_json) - expect(subject.errors).to be_nil - end - - context "and is html" do - let(:xml) { "

\n

" } - let(:box2) { '[{"type":"text","required":true,"label":"Birthday","name":"date"}]' } - - it "returns custom fields default values" do - expect(subject.to_json).to eq(bare_json) - expect(subject.errors).to be_nil - end - end - end - - context "when xml is malformed" do - context "and there's no textarea type in the definition" do - let(:box2) { '[{"type":"text","required":true,"label":"Birthday","name":"date"}]' } - let(:xml) { '
Age
44
Birthday
16/4/1980
' } - - it "returns original json and errors" do - expect(subject.to_json).to eq(bare_json) - expect(subject.errors).to include("DL/DD elements not found") - end - end - - context "and there's a textarea type in the definition" do - let(:xml) { "

I am a former text, written before definition of custom fields in this proposal.

" } - - it "returns original json and errors" do - expect(subject.to_json).to eq(compatible_json) - expect(subject.errors).to include("Content couldn't be parsed but has been assigned to the field 'Birthday'") - end - - context "and the textarea has no richtext" do - let(:box2) { '[{"type":"textarea","subtype":"textarea","required":true,"name":"date"}]' } - - it "assigns the text without html" do - expect(subject.to_json).to eq(compatible_text_json) - expect(subject.errors).to include("Content couldn't be parsed but has been assigned to the field 'date'") - end - end - - context "and text is not html" do - let(:xml) { "I am a former text, written before definition of custom fields in this proposal." } - let(:box2) { '[{"type":"textarea","subtype":"textarea","required":true,"name":"date"}]' } - - it "assigns the text without html" do - expect(subject.to_json).to eq(compatible_text_json) - expect(subject.errors).to include("Content couldn't be parsed but has been assigned to the field 'date'") - end - end - end - end - - context "when xml contains only one dd" do - let(:xml) { '
Birthday
16/4/1980
' } - - it "fills what's available" do - expect(subject.to_json).to eq(partial_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains arrays of divs" do - let(:xml) { '
Age
44
Birthday
16/4/1980
1/12/1880
' } - - it "fills what's available" do - expect(subject.to_json).to eq(array_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains only arrays of divs" do - let(:xml) { '
Birthday
16/4/1980
1/12/1880
' } - - it "fills what's available" do - expect(subject.to_json).to eq(partial_array_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains partial answers" do - let(:xml) { '
Name
Lucky Luke
Birthday
16/4/1980
' } - - it "fills what's available" do - expect(subject.to_json).to eq(partial_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains has no enclose div" do - let(:xml) { '
Age
44
Birthday
16/4/1980
' } - - it "fills what's available" do - expect(subject.to_json).to eq(partial_json) - expect(subject.errors).to be_nil - end - end - - context "when fields is not an array" do - let(:fields) { box2 } - - it "returns the json or one element" do - expect(subject.to_json).to eq(one_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains html inside div" do - let(:box1) { '[{"type":"text","required":true,"label":"Textarea","name":"textarea"}]' } - let(:xml) { '
Textarea

I am Pi!

Birthday
16/4/1980
' } - - it "collects all the inner html" do - expect(subject.to_json).to eq(html_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains utf-8 characters" do - let(:fields) { box1 } - let(:box1) { '[{"type":"textarea","required":true,"label":"Textarea","name":"textarea"}]' } - let(:xml) { '
Textarea
Test äöüéè👽
' } - - it "does not mangle them" do - expect(subject.to_json).to eq(utf8_json) - expect(subject.errors).to be_nil - end - end - - context "when xml contains a header" do - let(:box1) { '[{"type":"header","subtype":"h1","label":"Header"}]' } - let(:xml) { '
Birthday
16/4/1980
' } - - it "skips the header during parsing" do - expect(subject.to_json).to eq(header_json) - expect(subject.errors).to be_nil - end - end - - context "when values contain translation keys" do - let(:box1) { '[{"type":"text","required":true,"label":"custom_fields.age.label","name":"age","placeholder":"custom_fields.age.placeholder"}]' } - let(:box2) { '[{"type":"textarea","required":true,"label":"custom_fields.birthday.label","name":"date","placeholder":"custom_fields.birthday.placeholder"}]' } - let(:translations_de) do - { custom_fields: { age: { label: "Test 1", placeholder: "Test 2" }, birthday: { label: "Test 3", placeholder: "Test 4" } } } - end - let(:translations_ch) do - { custom_fields: { age: { label: "Test 5", placeholder: "Test 6" }, birthday: { label: "Test 7", placeholder: "Test 8" } } } - end - - before do - I18n.config.available_locales = [:en, :de, :ch, :at] - I18n.backend.store_translations(:de, translations_de) - I18n.backend.store_translations(:ch, translations_ch) - I18n.fallbacks = [:en] - end - - after do - I18n.config.available_locales = [:en, :ca, :es] - I18n.backend.reload! - I18n.fallbacks = [:en] - I18n.default_locale = :en - end - - it "translates to de" do - I18n.with_locale(:de) do - subject.translate! - - json = subject.to_json - expect(json[0]["label"]).to eq translations_de[:custom_fields][:age][:label] - expect(json[0]["placeholder"]).to eq translations_de[:custom_fields][:age][:placeholder] - expect(json[1]["label"]).to eq translations_de[:custom_fields][:birthday][:label] - expect(json[1]["placeholder"]).to eq translations_de[:custom_fields][:birthday][:placeholder] - end - end - - it "translates to ch" do - I18n.with_locale(:ch) do - subject.translate! - - json = subject.to_json - expect(json[0]["label"]).to eq translations_ch[:custom_fields][:age][:label] - expect(json[0]["placeholder"]).to eq translations_ch[:custom_fields][:age][:placeholder] - expect(json[1]["label"]).to eq translations_ch[:custom_fields][:birthday][:label] - expect(json[1]["placeholder"]).to eq translations_ch[:custom_fields][:birthday][:placeholder] - end - end - - it "ignores missing translation keys" do - I18n.with_locale(:at) do - subject.translate! - - json = subject.to_json - expect(json[0]["label"]).to eq "custom_fields.age.label" - expect(json[0]["placeholder"]).to eq "custom_fields.age.placeholder" - expect(json[1]["label"]).to eq "custom_fields.birthday.label" - expect(json[1]["placeholder"]).to eq "custom_fields.birthday.placeholder" - end - end - end - end -end diff --git a/spec/lib/voting_manifest_spec.rb b/spec/lib/voting_manifest_spec.rb deleted file mode 100644 index e6475dc..0000000 --- a/spec/lib/voting_manifest_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe VotingManifest do - subject { described_class.new(name: name) } - let(:name) { :test } - - it { is_expected.to be_valid } - - context "when no name" do - let(:name) { nil } - - it { is_expected.to be_invalid } - end - - it "any weight is valid" do - expect(subject).to be_valid_weight(0) - expect(subject).to be_valid_weight(1) - expect(subject).to be_valid_weight(1.5) - expect(subject).to be_valid_weight(-1.5) - end - - it "returns automatic labels" do - expect(subject.label_for(0)).to eq("weight_0") - expect(subject.label_for(1)).to eq("weight_1") - expect(subject.label_for(1.5)).to eq("weight_1.5") - expect(subject.label_for(-1.5)).to eq("weight_-1.5") - end - - context "when I18n labels exist" do - let(:name) { :voting_cards } - - it "returns I18n labels" do - expect(subject.label_for(0)).to eq("Abstain") - expect(subject.label_for(1)).to eq("Red") - expect(subject.label_for(2)).to eq("Yellow") - expect(subject.label_for(3)).to eq("Green") - expect(subject.label_for(3.5)).to eq("weight_3.5") - end - end - - context "when label_generator block" do - before do - subject.label_generator do |weight, _context| - "custom weight: #{weight.round}" - end - end - - it "returns custom labels" do - expect(subject.label_for(0)).to eq("custom weight: 0") - expect(subject.label_for(1)).to eq("custom weight: 1") - expect(subject.label_for(1.5)).to eq("custom weight: 2") - expect(subject.label_for(-1.5)).to eq("custom weight: -2") - end - end - - context "when weight_validator block" do - before do - subject.weight_validator do |weight, context| - next if context && context[:already_voted_this_weight] - - weight.in? [1, 2, 3, 4, 5] - end - end - - it "validates weights" do - expect(subject).to be_valid_weight(1) - expect(subject).to be_valid_weight(3) - expect(subject).to be_valid_weight(5) - expect(subject).not_to be_valid_weight(0) - expect(subject).not_to be_valid_weight(1.5) - expect(subject).not_to be_valid_weight(6) - end - - context "when context is set" do - let(:voted) { false } - let(:context) do - { - foo: "bar", - already_voted_this_weight: voted - } - end - - it "validates weights" do - expect(subject).to be_valid_weight(1, context) - expect(subject).not_to be_valid_weight(0, context) - expect(subject).to be_valid_weight(5, context) - expect(subject).not_to be_valid_weight(6, context) - end - - context "and voted" do - let(:voted) { true } - - it "validates weights" do - expect(subject).not_to be_valid_weight(1, context) - expect(subject).not_to be_valid_weight(0, context) - expect(subject).not_to be_valid_weight(5, context) - expect(subject).not_to be_valid_weight(6, context) - end - end - end - end - end -end diff --git a/spec/middleware/current_config_spec.rb b/spec/middleware/current_config_spec.rb deleted file mode 100644 index 3642f31..0000000 --- a/spec/middleware/current_config_spec.rb +++ /dev/null @@ -1,147 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/current_config_examples" - -module Decidim::DecidimAwesome - describe CurrentConfig do - let(:app) { ->(env) { [200, env, "app"] } } - let(:env) { Rack::MockRequest.env_for("https://#{host}/#{path}?foo=bar", "decidim.current_organization" => organization, method: method) } - let(:host) { "city.domain.org" } - let(:method) { "GET" } - let(:middleware) { described_class.new(app) } - let(:path) { "" } - let!(:organization) { create(:organization, host: host) } - let!(:organization2) { create(:organization, host: "another.host.org") } - let!(:assembly) { create(:assembly, organization: organization) } - let!(:another_assembly) { create(:assembly, organization: organization) } - let!(:user) { create(:user, :confirmed, name: "Bob Marley", organization: organization) } - let!(:admin) { create(:user, :confirmed, :admin, name: "Peter Green", organization: organization) } - - # clean the tampered User model - after do - Decidim::User.awesome_potential_admins = [] - Decidim::User.awesome_admins_for_current_scope = [] - end - - context "when no scoped admins" do - it_behaves_like "same environment" - it_behaves_like "untampered user model" - end - - context "when scoped admins" do - let!(:config) { create :awesome_config, organization: organization, var: :scoped_admins, value: admins } - let(:config_helper_bar) { create :awesome_config, organization: organization, var: :scoped_admin_bar } - let(:config_helper_foo) { create :awesome_config, organization: organization, var: :scoped_admin_foo } - let!(:constraint_bar) { create(:config_constraint, awesome_config: config_helper_bar, settings: settings_bar) } - let!(:constraint_foo) { create(:config_constraint, awesome_config: config_helper_foo, settings: settings_foo) } - let(:admins) do - { - "bar" => [] - } - end - let(:settings_bar) do - { - "participatory_space_manifest" => "assemblies", - "participatory_space_slug" => assembly.slug - } - end - let(:settings_foo) do - { - "participatory_space_manifest" => "participatory_processes" - } - end - let(:settings_none) do - { - "participatory_space_manifest" => "none" - } - end - - context "and no admins defined" do - it_behaves_like "same environment" - it_behaves_like "untampered user model" - end - - context "and admins are defined" do - let(:admins) do - { - "bar" => [admin.id.to_s, user.id.to_s], - "foo" => [admin.id.to_s] - } - end - - it_behaves_like "same environment" - it_behaves_like "tampered users model" - it_behaves_like "generic admin routes" - - context "and custom admins is disabled" do - before do - allow(Decidim::User).to receive(:respond_to?).with(:awesome_admins_for_current_scope).and_return(false) - end - - it "user model is not tampered" do - Decidim::User.awesome_admins_for_current_scope = nil - middleware.call(env) - - expect(Decidim::User.awesome_admins_for_current_scope).not_to be_present - end - end - - context "when visiting assemblies" do - let(:path) { "assemblies" } - - it_behaves_like "tampered users model" - end - - context "when visiting admin assemblies" do - let(:path) { "admin/assemblies" } - - it_behaves_like "tampered users model" - end - - context "when visiting admin assembly" do - let(:path) { "admin/assemblies/#{assembly.slug}" } - - it_behaves_like "tampered users model" - end - - context "when editing admin assembly" do - let(:path) { "admin/assemblies/#{assembly.id}" } - - it_behaves_like "untampered user model" - - context "and is POST" do - let(:method) { "POST" } - - it_behaves_like "tampered users model" - end - - context "and is PATCH" do - let(:method) { "PATCH" } - - it_behaves_like "tampered users model" - end - end - - context "when visiting processes" do - let(:path) { "processes" } - - it_behaves_like "tampered admin model" - end - - context "when visiting admin processes" do - let(:path) { "admin/processes" } - - it_behaves_like "tampered admin model" - end - - context "and user have the none constraint" do - let!(:constraint_bar2) { create(:config_constraint, awesome_config: config_helper_bar, settings: settings_none) } - - it_behaves_like "same environment" - it_behaves_like "tampered admin model" - end - end - end - end -end diff --git a/spec/models/editor_image_spec.rb b/spec/models/editor_image_spec.rb deleted file mode 100644 index f1ae1ea..0000000 --- a/spec/models/editor_image_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe EditorImage do - subject { editor_image } - - let(:organization) { create(:organization) } - let(:user) { create(:user) } - let(:editor_image) { create(:awesome_editor_image, organization: organization, author: user) } - - it { is_expected.to be_valid } - - it "editor_image is associated with user and organization" do - expect(subject).to eq(editor_image) - expect(subject.organization).to eq(organization) - expect(subject.author).to eq(user) - end - end -end diff --git a/spec/models/paper_trail_version_spec.rb b/spec/models/paper_trail_version_spec.rb deleted file mode 100644 index 00ac2aa..0000000 --- a/spec/models/paper_trail_version_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -module Decidim::DecidimAwesome - describe PaperTrailVersion, type: :model do - subject { paper_trail_version } - - let(:organization) { create(:organization) } - let(:user) { create(:user, organization: organization) } - - let(:external_organization) { create(:organization) } - let(:external_user) { create(:user, organization: external_organization) } - - context "when user roles" do - let(:participatory_process_user_role) { create(:participatory_process_user_role, participatory_process: participatory_process, user: administrator, role: "admin", created_at: 1.day.ago) } - let(:administrator) { create(:user, organization: organization, last_sign_in_at: 1.day.ago) } - let(:participatory_process) { create(:participatory_process, organization: organization) } - let!(:paper_trail_version) { create(:paper_trail_version, item_type: "Decidim::ParticipatoryProcessUserRole", item_id: participatory_process_user_role.id, whodunnit: user.id, event: "create") } - - let(:external_participatory_process_user_role) { create(:participatory_process_user_role, participatory_process: external_participatory_process, user: external_valuator, role: "valuator", created_at: 1.day.ago) } - let(:external_valuator) { create(:user, organization: external_organization, last_sign_in_at: 1.day.ago) } - let(:external_participatory_process) { create(:participatory_process, organization: external_organization) } - let!(:external_paper_trail_version) { create(:paper_trail_version, item_type: "Decidim::ParticipatoryProcessUserRole", item_id: external_participatory_process_user_role.id, whodunnit: external_user.id, event: "create") } - - before do - paper_trail_version.update!( - object_changes: { - "decidim_user_id" => [nil, administrator.id], - "decidim_participatory_process_id" => [nil, participatory_process.id] - }.to_yaml - ) - - external_paper_trail_version.update!( - object_changes: { - "decidim_user_id" => [nil, external_valuator.id], - "decidim_participatory_process_id" => [nil, external_participatory_process.id] - }.to_yaml - ) - end - - it { is_expected.to be_valid } - - it "paper_trail_version is associated with user" do - expect(subject.whodunnit).to eq(user.id.to_s) - expect(external_paper_trail_version.whodunnit).to eq(external_user.id.to_s) - end - - it "returns default_scope ordered by created_at" do - expect(PaperTrailVersion.all).to eq([external_paper_trail_version, paper_trail_version]) - end - - it "returns space_role_actions scope correctly" do - expect(PaperTrailVersion.space_role_actions(organization)).to include(paper_trail_version) - expect(PaperTrailVersion.space_role_actions(organization)).not_to include(external_paper_trail_version) - expect(PaperTrailVersion.space_role_actions(external_organization)).to include(external_paper_trail_version) - expect(PaperTrailVersion.space_role_actions(external_organization)).not_to include(paper_trail_version) - end - - it "present method returns a PaperTrailBasePresenter object" do - expect(subject.present).to be_a(PaperTrailBasePresenter) - end - - it "present method returns a ParticipatorySpaceRolePresenter object" do - expect(subject.present).to be_a(ParticipatorySpaceRolePresenter) - end - end - - context "when admin roles" do - let!(:paper_trail_version) { create(:paper_trail_version, item_type: "Decidim::UserBaseEntity", item_id: user.id, event: "create") } - let!(:external_paper_trail_version) { create(:paper_trail_version, item_type: "Decidim::UserBaseEntity", item_id: external_user.id, event: "create") } - - before do - paper_trail_version.update!( - object_changes: { - "admin" => [false, true] - }.to_yaml - ) - - external_paper_trail_version.update!( - object_changes: { - "roles" => [[], ["valuator"]] - }.to_yaml - ) - end - - it "returns default_scope ordered by created_at" do - expect(PaperTrailVersion.all).to eq([external_paper_trail_version, paper_trail_version]) - expect(PaperTrailVersion.admin_role_actions).to match_array([external_paper_trail_version, paper_trail_version]) - end - - it "present method returns a UserEntityPresenter object" do - expect(subject.present).to be_a(UserEntityPresenter) - expect(external_paper_trail_version.present).to be_a(UserEntityPresenter) - end - - it "returns admin_role_actions scope correctly" do - expect(PaperTrailVersion.in_organization(organization).admin_role_actions).to include(paper_trail_version) - expect(PaperTrailVersion.in_organization(organization).admin_role_actions).not_to include(external_paper_trail_version) - expect(PaperTrailVersion.in_organization(external_organization).admin_role_actions).to include(external_paper_trail_version) - expect(PaperTrailVersion.in_organization(external_organization).admin_role_actions).not_to include(paper_trail_version) - end - - it "filters correctly by role" do - expect(PaperTrailVersion.in_organization(organization).admin_role_actions("admin")).to include(paper_trail_version) - expect(PaperTrailVersion.in_organization(organization).admin_role_actions("valuator")).to eq([]) - expect(PaperTrailVersion.in_organization(external_organization).admin_role_actions("valuator")).to include(external_paper_trail_version) - expect(PaperTrailVersion.in_organization(external_organization).admin_role_actions("admin")).to eq([]) - end - end - end -end diff --git a/spec/models/proposal_extra_field_spec.rb b/spec/models/proposal_extra_field_spec.rb deleted file mode 100644 index 8c22275..0000000 --- a/spec/models/proposal_extra_field_spec.rb +++ /dev/null @@ -1,217 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe ProposalExtraField do - subject { extra_fields } - - let(:extra_fields) { create(:awesome_proposal_extra_fields) } - let(:proposal) { create(:proposal) } - - it { is_expected.to be_valid } - - it "has a proposal associated" do - expect(extra_fields.proposal).to be_a(Decidim::Proposals::Proposal) - end - - it "the associated proposal has a weight cache" do - expect(extra_fields.proposal.extra_fields).to eq(extra_fields) - end - - describe "weight_count" do - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - ] - end - - it "returns the weight count for a weight" do - expect(proposal.weight_count(1)).to eq(1) - expect(proposal.weight_count(2)).to eq(1) - expect(proposal.weight_count(3)).to eq(1) - end - - context "when a vote is added" do - before do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 5) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - end - - it "returns the weight count for a weight" do - expect(proposal.weight_count(1)).to eq(1) - expect(proposal.weight_count(2)).to eq(1) - expect(proposal.weight_count(3)).to eq(2) - expect(proposal.weight_count(4)).to eq(0) - expect(proposal.weight_count(5)).to eq(1) - end - end - - context "when extra_fields does not exist" do - let(:extra_fields) { nil } - let(:vote_weights) { nil } - - it "returns 0" do - expect(proposal.weight_count(1)).to eq(0) - expect(proposal.weight_count(2)).to eq(0) - expect(proposal.weight_count(3)).to eq(0) - expect(proposal.weight_count(100)).to eq(0) - end - - context "when a vote is added" do - before do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 5) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - end - - it "returns the weight count for a weight" do - expect(proposal.weight_count(1)).to eq(0) - expect(proposal.weight_count(2)).to eq(0) - expect(proposal.weight_count(3)).to eq(1) - expect(proposal.weight_count(4)).to eq(0) - expect(proposal.weight_count(5)).to eq(1) - end - end - end - end - - context "when proposal is destroyed" do - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - - it "destroys the proposal weight" do - expect { proposal.destroy }.to change(Decidim::DecidimAwesome::ProposalExtraField, :count).by(-1) - end - end - - context "when proposal weight is destroyed" do - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - - it "does not destroy the proposal" do - expect { extra_fields.destroy }.not_to change(Decidim::Proposals::ProposalVote, :count) - end - end - - context "when vote weight is" do - describe "created" do - it "increments the weight cache" do - expect { create(:proposal_vote, proposal: proposal) }.to change { proposal.votes.count }.by(1) - expect { create(:awesome_vote_weight, vote: proposal.votes.first, weight: 3) }.to change(Decidim::DecidimAwesome::ProposalExtraField, :count).by(1) - expect(proposal.extra_fields.vote_weight_totals).to eq({ "3" => 1 }) - expect(proposal.extra_fields.weight_total).to eq(3) - end - - context "when cache already exists" do - let(:another_proposal) { create :proposal, component: proposal.component } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, :with_votes, proposal: proposal) } - let!(:another_extra_fields) { create(:awesome_proposal_extra_fields, :with_votes, proposal: another_proposal) } - - it "has weights and votes" do - expect(extra_fields.reload.vote_weight_totals).to eq({ "1" => 1, "2" => 1, "3" => 1, "4" => 1, "5" => 1 }) - expect(extra_fields.weight_total).to eq(15) - end - - it "increments the weight cache" do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - expect(extra_fields.reload.vote_weight_totals).to eq({ "1" => 2, "2" => 1, "3" => 3, "4" => 1, "5" => 1 }) - expect(extra_fields.weight_total).to eq(22) - end - end - - context "when cache does not exist yet" do - let(:extra_fields) { proposal.reload.extra_fields } - - it "has no weights and votes" do - expect(extra_fields).to be_nil - end - - it "increments the weight cache" do - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - expect(extra_fields.vote_weight_totals).to eq({ "1" => 1, "3" => 2 }) - expect(extra_fields.weight_total).to eq(7) - end - end - end - - # this is an unlikely scenario where voting removes and creates new vote weights, just in case... - describe "updated" do - let!(:vote_weight1) { create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1) } - let!(:vote_weight2) { create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2) } - let(:extra_fields) { proposal.reload.extra_fields } - - it "increments the weight cache" do - vote_weight1.weight = 3 - vote_weight1.save - expect(extra_fields.vote_weight_totals).to eq({ "2" => 1, "3" => 1 }) - expect(extra_fields.weight_total).to eq(5) - end - - it "decreases the weight cache" do - vote_weight2.weight = 1 - vote_weight2.save - expect(extra_fields.vote_weight_totals).to eq({ "1" => 2 }) - expect(extra_fields.weight_total).to eq(2) - end - end - - describe "destroyed" do - let!(:vote_weight1) { create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1) } - let!(:vote_weight2) { create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2) } - let(:extra_fields) { proposal.reload.extra_fields } - - it "decreases the weight cache" do - vote_weight1.destroy - expect(extra_fields.vote_weight_totals).to eq({ "2" => 1 }) - expect(extra_fields.weight_total).to eq(2) - end - end - end - - describe "all_vote_weights" do - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let!(:another_extra_fields) { create(:awesome_proposal_extra_fields, proposal: another_proposal) } - let!(:unrelated_another_extra_fields) { create(:awesome_proposal_extra_fields, :with_votes) } - let(:another_proposal) { create(:proposal, component: proposal.component) } - let!(:votes) do - vote = create(:proposal_vote, proposal: proposal, author: create(:user, organization: proposal.organization)) - create(:awesome_vote_weight, vote: vote, weight: 1) - end - let!(:other_votes) do - vote = create(:proposal_vote, proposal: another_proposal, author: create(:user, organization: proposal.organization)) - create(:awesome_vote_weight, vote: vote, weight: 2) - end - - it "returns all vote weights for a component" do - expect(proposal.all_vote_weights).to match_array([1, 2]) - expect(another_proposal.all_vote_weights).to match_array([1, 2]) - expect(proposal.vote_weights).to eq({ "1" => 1, "2" => 0 }) - expect(another_proposal.vote_weights).to eq({ "1" => 0, "2" => 1 }) - end - - context "when wrong cache exists" do - before do - # rubocop:disable Rails/SkipsModelValidations: - # we don't want to trigger the active record hooks - extra_fields.update_columns(vote_weight_totals: { "3" => 1, "4" => 1 }) - # rubocop:enable Rails/SkipsModelValidations: - end - - it "returns all vote weights for a component" do - expect(proposal.extra_fields.vote_weight_totals).to eq({ "3" => 1, "4" => 1 }) - expect(proposal.vote_weights).to eq({ "1" => 0, "2" => 0 }) - proposal.update_vote_weights! - expect(proposal.vote_weights).to eq({ "1" => 1, "2" => 0 }) - expect(another_proposal.vote_weights).to eq({ "1" => 0, "2" => 1 }) - expect(proposal.extra_fields.vote_weight_totals).to eq({ "1" => 1 }) - expect(another_proposal.extra_fields.vote_weight_totals).to eq({ "2" => 1 }) - end - end - end - end -end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 954b068..35e5a4f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -29,35 +29,5 @@ module Decidim expect(subject).to be_admin end end - - context "when list is an empty array" do - before do - User.awesome_admins_for_current_scope = [] - end - - it_behaves_like "not admin" - end - - context "when list is nil" do - before do - User.awesome_admins_for_current_scope = nil - end - - it_behaves_like "not admin" - end - - context "when user is already an admin" do - let(:user) { create(:user, :admin) } - - it_behaves_like "is admin" - end - - context "when admin is listed in the current scope" do - before do - User.awesome_admins_for_current_scope = [user.id] - end - - it_behaves_like "is admin" - end end end diff --git a/spec/models/vote_weight_spec.rb b/spec/models/vote_weight_spec.rb deleted file mode 100644 index 2d486c7..0000000 --- a/spec/models/vote_weight_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe VoteWeight do - subject { vote_weight } - - let(:vote_weight) { create(:awesome_vote_weight) } - - it { is_expected.to be_valid } - - it "has a vote associated" do - expect(vote_weight.vote).to be_a(Decidim::Proposals::ProposalVote) - end - - it "the associated proposal vote has a vote weight" do - expect(vote_weight.vote.vote_weight).to eq(vote_weight) - end - - context "when vote is destroyed" do - let(:vote) { create(:proposal_vote) } - let!(:vote_weight) { create(:awesome_vote_weight, vote: vote) } - - it "destroys the vote weight" do - expect { vote.destroy }.to change(Decidim::DecidimAwesome::VoteWeight, :count).by(-1) - end - end - - context "when vote weight is destroyed" do - let(:vote) { create(:proposal_vote) } - let!(:vote_weight) { create(:awesome_vote_weight, vote: vote) } - - it "does not destroy the vote" do - expect { vote_weight.destroy }.not_to change(Decidim::Proposals::ProposalVote, :count) - end - end - - describe "weight" do - let(:vote) { create(:proposal_vote) } - - context "when vote_weight already exists" do - let!(:vote_weight) { create(:awesome_vote_weight, vote: vote, weight: 1) } - - it "can be changed" do - expect(vote.weight).to eq(1) - vote.weight = 3 - expect(vote.weight).to eq(3) - expect(vote_weight.reload.weight).to eq(3) - end - end - - context "when vote_weight does not exist" do - let(:vote_weight) { VoteWeight.last } - - it "can be set" do - expect(vote.weight).to be_nil - vote.weight = 3 - expect(vote.weight).to eq(3) - expect(vote_weight.weight).to eq(3) - end - end - end - end -end diff --git a/spec/presenters/menu_presenter_spec.rb b/spec/presenters/menu_presenter_spec.rb deleted file mode 100644 index a256c68..0000000 --- a/spec/presenters/menu_presenter_spec.rb +++ /dev/null @@ -1,164 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim - describe MenuPresenter, type: :helper do - subject { MenuPresenter.new(:custom_menu, view) } - - let(:override) do - [{ - url: "/foo", - label: { - "en" => "Fumanchu" - }, - position: 10 - }, - { - url: "/baz", - label: { - "en" => "Baz" - }, - position: 3 - }] - end - let(:user) { create :user, organization: organization } - let(:organization) { create :organization } - let!(:config) { create :awesome_config, organization: organization, var: :custom_menu, value: override } - - before do - allow(view).to receive(:current_organization).and_return(organization) - allow(view).to receive(:current_user).and_return(user) - MenuRegistry.register :custom_menu do |menu| - menu.add_item :native_foo, "Foo", "/foo", position: 1 - menu.add_item :native_bar, "Bar", "/bar", position: 2 - menu.add_item :native_baz, "Baz", "/baz", if: Time.current.year == 2000 - menu.add_item :native_hid, "Hid", "/hid", if: Time.current.year == 2000 - end - end - - after do - MenuRegistry.destroy(:custom_menu) - Decidim::DecidimAwesome.config.except!(:custom_menu) - end - - shared_context "when an item is removed" do - before do - Decidim.menu :custom_menu do |menu| - menu.remove_item :native_bar - end - end - end - - shared_examples "has default items" do - it "renders the menu as a navigation list and skips non visible" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li", count: 2) & - have_link("Foo", href: "/foo") & - have_link("Bar", href: "/bar") - end - - it "renders the menu in the right order" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li:first-child", text: "Foo") & - have_selector("li:last-child", text: "Bar") - end - - it "returns instance of Decidim:Menu" do - expect(subject.evaluated_menu).to be_a(Decidim::Menu) - end - end - - shared_examples "has overridden items" do - it "renders the menu as a navigation list" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li", count: 3) & - have_link("Bar", href: "/bar") & - have_link("Fumanchu", href: "/foo") & - have_link("Baz", href: "/baz") - end - - it "renders the menu in the right order" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li:first-child", text: "Bar") & - have_selector("li:last-child", text: "Fumanchu") - end - - it "returns instance of Decidim:Menu" do - expect(subject.evaluated_menu).to be_a(Decidim::DecidimAwesome::MenuHacker) - end - end - - shared_examples "removed item is not present" do - include_context "when an item is removed" - - it "renders the menu as a navigation list" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li", count: 1) & - have_link("Foo", href: "/foo") - end - - it "renders the menu in the right order" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li:first-child", text: "Foo") & - have_selector("li:last-child", text: "Foo") - end - - it "returns instance of Decidim:Menu" do - expect(subject.evaluated_menu).to be_a(Decidim::Menu) - end - end - - shared_examples "removed item is not present and other items are overridden" do - include_context "when an item is removed" - - it "renders the menu as a navigation list" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li", count: 2) & - have_link("Baz", href: "/baz") & - have_link("Fumanchu", href: "/foo") - end - - it "renders the menu in the right order" do - expect(subject.render).to \ - have_selector("ul") & - have_selector("li:first-child", text: "Baz") & - have_selector("li:last-child", text: "Fumanchu") - end - - it "returns instance of Decidim:Menu" do - expect(subject.evaluated_menu).to be_a(Decidim::DecidimAwesome::MenuHacker) - end - end - - context "when overrode menu is not an awesome config var" do - it_behaves_like "has default items" - it_behaves_like "removed item is not present" - end - - context "when overrode menu is disabled" do - before do - Decidim::DecidimAwesome.config[:custom_menu] = :disabled - end - - it_behaves_like "has default items" - it_behaves_like "removed item is not present" - end - - context "when overrode menu is enabled" do - before do - Decidim::DecidimAwesome.config[:custom_menu] = [] - end - - it_behaves_like "has overridden items" - it_behaves_like "removed item is not present and other items are overridden" - end - end -end diff --git a/spec/presenters/participatory_space_role_presenter_spec.rb b/spec/presenters/participatory_space_role_presenter_spec.rb deleted file mode 100644 index 844ed27..0000000 --- a/spec/presenters/participatory_space_role_presenter_spec.rb +++ /dev/null @@ -1,130 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/action_log_presenter_examples" - -module Decidim::DecidimAwesome - describe ParticipatorySpaceRolePresenter, type: :helper do - let(:user) { create :user, organization: organization, last_sign_in_at: last_sign_in_at } - let(:last_sign_in_at) { nil } - let(:entry) { Decidim::DecidimAwesome::PaperTrailVersion.space_role_actions(organization).first } - let!(:organization) { create :organization } - let(:participatory_space) { create(:participatory_process, organization: organization) } - let(:role) { "admin" } - let!(:participatory_process_user_role) { create(:participatory_process_user_role, role: role, participatory_process: participatory_space, user: user) } - let(:destroyed_at) { 2.days.ago } - - let(:html) { true } - - subject { described_class.new(entry, html: html) } - - shared_context "with role destroyed" do - before do - participatory_process_user_role.destroy! - Decidim::DecidimAwesome::PaperTrailVersion.first.update!(created_at: destroyed_at) - end - end - - with_versioning do - describe "#role" do - it "returns the role" do - expect(subject.role).to eq("admin") - end - - it "returns the role name in html" do - expect(subject.role_name).to eq("Administrator") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns without classes" do - expect(subject.role_name).to eq("Administrator") - end - end - - context "when role is a valuator" do - let(:role) { "valuator" } - - it "returns the role name in html" do - expect(subject.role_name).to eq("Valuator") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns without classes" do - expect(subject.role_name).to eq("Valuator") - end - end - end - - context "when role is a collaborator" do - let(:role) { "collaborator" } - - it "returns the role name in html" do - expect(subject.role_name).to eq("Collaborator") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns without classes" do - expect(subject.role_name).to eq("Collaborator") - end - end - end - end - - it_behaves_like "a user presenter" - - describe "#participatory_space_name" do - it "returns the participatory space name" do - expect(subject.participatory_space_name).to include("Processes") - end - end - - describe "#participatory_space_type" do - it "returns the participatory space type" do - expect(subject.participatory_space_type).to eq("Processes") - end - end - - describe "#participatory_space_path" do - it "returns the path to user roles" do - expect(subject.participatory_space_path).to eq("/admin/participatory_processes/#{participatory_space.slug}/user_roles") - end - - context "when role is destroyed" do - include_context "with role destroyed" - - it "returns the path to user roles" do - expect(subject.participatory_space_path).to eq("/admin/participatory_processes/#{participatory_space.slug}/user_roles") - end - end - - # rubocop:disable RSpec/AnyInstance - context "when no user roles route exist" do - before do - allow_any_instance_of(Decidim::EngineRouter).to receive(:participatory_process_user_roles_path).and_raise(NoMethodError) - end - - it "returns the path to user roles" do - expect(subject.participatory_space_path.split("?").first).to eq("/admin/participatory_processes/#{participatory_space.slug}") - end - - context "when no participatory_space route exist" do - before do - allow_any_instance_of(Decidim::EngineRouter).to receive(:participatory_process_path).and_raise(NoMethodError) - end - - it "returns empty" do - expect(subject.participatory_space_path).to be_blank - end - end - end - # rubocop:enable RSpec/AnyInstance - end - end - end -end diff --git a/spec/presenters/role_base_presenter_spec.rb b/spec/presenters/role_base_presenter_spec.rb deleted file mode 100644 index b279150..0000000 --- a/spec/presenters/role_base_presenter_spec.rb +++ /dev/null @@ -1,117 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::DecidimAwesome - describe RoleBasePresenter, type: :helper do - let(:user) { create :user, organization: organization } - let(:organization) { create :organization } - let(:participatory_space) { create(:participatory_process, organization: organization) } - let(:role) { "admin" } - let(:participatory_process_user_role) { create(:participatory_process_user_role, role: role, participatory_process: participatory_space, user: user) } - let(:changes_create) do - { - "decidim_user_id" => [nil, user.id], - "decidim_participatory_process_id" => [nil, participatory_space.id], - "role" => [nil, role] - } - end - let!(:entry) do - create(:paper_trail_version, item: participatory_process_user_role, - created_at: 1.week.ago, - event: "create") - end - - let(:html) { true } - - subject { described_class.new(entry, html: html) } - - before do - allow(entry).to receive(:changeset).and_return(changes_create) - end - - describe "#role_name" do - it "raises implementation exception" do - expect { subject.role_name }.to raise_exception(RuntimeError) - end - end - - describe "#user" do - it "raises implementation exception" do - expect { subject.user }.to raise_exception(RuntimeError) - end - - context "when user is missing" do - before do - allow(subject).to receive(:user).and_return(nil) - end - - it "returns emtpy email" do - expect(subject.user_email).to be_blank - end - - it "returns missing user" do - expect(subject.user_name).to include("User not in the database") - end - end - - context "when user is deleted" do - let(:deleted) { double(deleted?: true) } - - before do - allow(subject).to receive(:user).and_return(deleted) - end - - it "returns deleted user" do - expect(subject.user_name).to include("Deleted user") - end - end - end - - describe "#removal_date" do - it "returns currently active" do - expect(subject.removal_date).to eq("Currently active") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns currently active" do - expect(subject.removal_date).to eq("Currently active") - end - end - end - - describe "#participatory_space_name" do - it "returns the participatory space name" do - expect(subject.participatory_space_name).to be_blank - end - end - - describe "#participatory_space_type" do - it "returns the participatory space type" do - expect(subject.participatory_space_type).to be_blank - end - end - - describe "#participatory_space_path" do - it "returns the path to user roles" do - expect(subject.participatory_space_path).to be_blank - end - end - - describe "#created_date" do - it "returns the creation date" do - expect(subject.created_date).to eq(entry.created_at.strftime("%d/%m/%Y %H:%M")) - end - - context "when date is missing" do - let(:entry) { nil } - - it "returns the creation date" do - expect(subject.created_date).to eq("") - end - end - end - end -end diff --git a/spec/presenters/user_entity_presenter_spec.rb b/spec/presenters/user_entity_presenter_spec.rb deleted file mode 100644 index e7183c6..0000000 --- a/spec/presenters/user_entity_presenter_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/action_log_presenter_examples" - -module Decidim::DecidimAwesome - describe UserEntityPresenter, type: :helper do - let!(:user) { create :user, :admin, organization: organization, last_sign_in_at: last_sign_in_at } - let(:entry) { Decidim::DecidimAwesome::PaperTrailVersion.admin_role_actions.first } - let(:last_sign_in_at) { nil } - let(:organization) { create :organization } - let(:destroyed_at) { 2.days.ago } - - let(:html) { true } - - subject { described_class.new(entry, html: html) } - - shared_context "with role destroyed" do - before do - user.admin = false - user.roles = [] - user.save! - Decidim::DecidimAwesome::PaperTrailVersion.first.update!(created_at: destroyed_at) - end - end - - with_versioning do - describe "#roles" do - it "returns the roles" do - expect(subject.roles).to eq(["admin"]) - end - - it "returns the role name in html" do - expect(subject.role_name).to eq("Super admin") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns without classes" do - expect(subject.role_name).to eq("Super admin") - end - end - end - - it_behaves_like "a user presenter" - - context "when the role is a participant manager" do - let!(:user) { create :user, :user_manager, organization: organization, last_sign_in_at: last_sign_in_at } - let(:entry) { Decidim::DecidimAwesome::PaperTrailVersion.admin_role_actions.first } - - describe "#roles" do - it "returns the roles" do - expect(subject.roles).to eq(["user_manager"]) - end - - it "returns the role name in html" do - expect(subject.role_name).to eq("User manager") - end - - context "when html is disabled" do - let(:html) { false } - - it "returns without classes" do - expect(subject.role_name).to eq("User manager") - end - end - end - - it_behaves_like "a user presenter" - end - end - end -end diff --git a/spec/serializers/proposal_serializer_spec.rb b/spec/serializers/proposal_serializer_spec.rb deleted file mode 100644 index bfd99c0..0000000 --- a/spec/serializers/proposal_serializer_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Proposals - describe ProposalSerializer do - subject do - described_class.new(proposal) - end - - let!(:proposal) { create(:proposal, :accepted, component: component) } - let!(:another_proposal) { create(:proposal, :accepted, component: component) } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, proposal: proposal) } - let(:weights) do - { - "0" => 1, - "3" => 2 - } - end - let!(:votes) do - weights.each do |weight, count| - count.times do - vote = create(:proposal_vote, proposal: proposal, author: create(:user, organization: proposal.organization)) - create(:awesome_vote_weight, vote: vote, weight: weight) - end - end - end - let!(:another_extra_fields) { create(:awesome_proposal_extra_fields, :with_votes, proposal: another_proposal) } - let(:participatory_process) { component.participatory_space } - let(:component) { create :proposal_component, settings: settings } - let(:settings) do - { - awesome_voting_manifest: manifest - } - end - let(:labeled_weights) do - { - "Abstain" => 1, - "Red" => 0, - "Yellow" => 0, - "Green" => 2, - "weight_4" => 0, - "weight_5" => 0 - } - end - let(:manifest) { :voting_cards } - - let!(:proposals_component) { create(:component, manifest_name: "proposals", participatory_space: participatory_process) } - - describe "#serialize" do - let(:serialized) { subject.serialize } - - it "serializes the id" do - expect(serialized).to include(id: proposal.id) - end - - it "serializes the amount of supports" do - expect(serialized).to include(supports: proposal.proposal_votes_count) - end - - it "serializes the weights" do - expect(serialized).to include(weights: labeled_weights) - end - - context "when no manifest" do - let(:manifest) { nil } - - it "serializes the weights" do - expect(serialized).to include(weights: { "0" => 1, "1" => 0, "2" => 0, "3" => 2, "4" => 0, "5" => 0 }) - end - end - - context "when vote_cache is outdated" do - let(:wrong_weights) do - { "1" => 101, "2" => 102, "3" => 103, "4" => 104, "5" => 105 } - end - let(:labeled_wrong_weights) do - { "Abstain" => 0, "Red" => 101, "Yellow" => 102, "Green" => 103, "weight_4" => 104, "weight_5" => 105 } - end - - before do - # rubocop:disable Rails/SkipsModelValidations: - # we don't want to trigger the active record hooks - extra_fields.update_columns(vote_weight_totals: wrong_weights) - # rubocop:enable Rails/SkipsModelValidations: - end - - it "serializes the weights" do - expect(proposal.vote_weights).to eq(labeled_wrong_weights) - expect(serialized).to include(weights: labeled_weights) - extra_fields.reload - expect(proposal.reload.vote_weights).to eq(labeled_weights) - end - end - end - end -end diff --git a/spec/system/admin/admin_accountability_admin_filtering_spec.rb b/spec/system/admin/admin_accountability_admin_filtering_spec.rb deleted file mode 100644 index 02c4a39..0000000 --- a/spec/system/admin/admin_accountability_admin_filtering_spec.rb +++ /dev/null @@ -1,190 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Filter Admin actions", type: :system do - let(:login_date) { 3.days.ago } - let(:organization) { create :organization } - let!(:user) { create :user, :confirmed, organization: organization } - let!(:admin) { create :user, :admin, :confirmed, organization: organization } - let!(:admin2) { create(:user, :admin, :confirmed, name: "Lorry 1", email: "test@test.com", organization: organization, created_at: 6.days.ago) } - let!(:manager) { create(:user, :user_manager, :confirmed, organization: organization, created_at: 5.days.ago, last_sign_in_at: login_date) } - let!(:manager2) { create(:user, :user_manager, :confirmed, name: "Lorry 2", email: "test2@test.com", organization: organization, created_at: 4.days.ago) } - - let(:resource_controller) { Decidim::DecidimAwesome::Admin::AdminAccountabilityController } - - include_context "with filterable context" - - before do - # ensure papertrail has the same created_at date as the object being mocked - Decidim::DecidimAwesome::PaperTrailVersion.admin_role_actions.map { |v| v.update(created_at: v.item.created_at) } - - switch_to_host(organization.host) - login_as admin, scope: :user - - visit decidim_admin_decidim_awesome.admin_accountability_path - - click_link "List global admins" - end - - def apply_admin_filter(options, filter) - within(".filters__section") do - find_link("Filter").hover - find_link(options).hover - click_link(filter) - end - end - - with_versioning do - it "shows filters" do - expect(page).to have_content("Filter") - expect(page).to have_css("#q_user_name_or_user_email_cont") - expect(page).to have_css("#q_created_at_gteq") - expect(page).to have_css("#q_created_at_lteq") - end - - it "displays the filter labels" do - find("a.dropdown").hover - expect(page).not_to have_content("Participatory space type") - expect(page).to have_content("Role type") - - find("a", text: "Role type").hover - - within ".filters__section" do - expect(page).to have_content("Super admin") - expect(page).to have_content("User manager") - end - end - - it "displays all the admins" do - expect(page).to have_content("Super admin", count: 2) - expect(page).to have_content("User manager", count: 2) - expect(page).to have_content(admin.name, count: 1) - expect(page).to have_content(admin2.name, count: 1) - expect(page).to have_content(manager.name, count: 1) - expect(page).to have_content(manager2.name, count: 1) - expect(page).not_to have_content(user.name, count: 1) - - expect(page).to have_content(login_date.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active", count: 4) - end - - context "when filtering admin_actions by ROLE TYPE" do - it "Admin role type" do - apply_admin_filter("Role type", "Super admin") - - within "tbody" do - expect(page).to have_content("Super admin", count: 2) - end - end - - it "User manager role type" do - apply_admin_filter("Role type", "User manager") - - within "tbody" do - expect(page).to have_content("User manager", count: 2) - end - end - end - - context "when searching by name or email" do - it "searches by name" do - search_by_text("Lorry") - - within "tbody" do - expect(page).to have_content("Lorry", count: 2) - end - end - - it "searches by email" do - search_by_text("@test.com") - - within "tbody" do - expect(page).to have_content("@test.com", count: 2) - end - end - end - - context "when searching by date" do - def search_by_date(start_date, end_date) - within(".filters__section") do - fill_in(:q_created_at_gteq, with: start_date) if start_date.present? - fill_in(:q_created_at_lteq, with: end_date) if end_date.present? - - find("*[type=submit]").click - end - end - - context "when the start date is earlier" do - it "displays all entries" do - search_by_date(7.days.ago, "") - - within "tbody" do - expect(page).to have_css("tr", count: 4) - end - end - end - - context "when the start date is later" do - it "displays no entries" do - search_by_date(1.day.from_now, "") - - within "tbody" do - expect(page).to have_css("tr", count: 0) - end - end - end - - context "when the end date is later" do - it "displays all entries" do - search_by_date("", 5.days.from_now) - - within "tbody" do - expect(page).to have_css("tr", count: 4) - end - end - end - - context "when the end date is earlier" do - it "displays no entries" do - search_by_date("", 7.days.ago) - - within "tbody" do - expect(page).to have_css("tr", count: 0) - end - end - end - - context "when searching in range" do - it "displays entries in range" do - search_by_date(6.days.ago, 5.days.ago) - - within "tbody" do - expect(page).to have_css("tr", count: 2) - expect(page).to have_content("Super admin", count: 1) - expect(page).to have_content("User manager", count: 1) - expect(page).to have_content(admin2.name, count: 1) - expect(page).to have_content(manager.name, count: 1) - end - end - - it "exports the result" do - search_by_date(6.days.ago, 5.days.ago) - - find(".exports.dropdown").click - perform_enqueued_jobs { click_link "Export as CSV" } - - within ".callout.success" do - expect(page).to have_content("Export job has been enqueued. You will receive an email when it's ready.") - end - - expect(last_email.subject).to include("Your export", "csv", "is ready") - expect(last_email.attachments.length).to be_positive - expect(last_email.attachments.first.filename).to match(/^admin_actions.*\.zip$/) - expect(current_url).to include(decidim_admin_decidim_awesome.admin_accountability_path) - expect(current_url).to include("admins=true") - end - end - end - end -end diff --git a/spec/system/admin/admin_accountability_ps_filtering_spec.rb b/spec/system/admin/admin_accountability_ps_filtering_spec.rb deleted file mode 100644 index b78a935..0000000 --- a/spec/system/admin/admin_accountability_ps_filtering_spec.rb +++ /dev/null @@ -1,221 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Filter Admin actions", type: :system do - let(:user_creation_date) { 7.days.ago } - let(:login_date) { 6.days.ago } - let!(:organization) { create :organization } - let!(:admin) { create :user, :admin, :confirmed, organization: organization } - let(:administrator) { create(:user, organization: organization, last_sign_in_at: login_date, created_at: user_creation_date) } - let(:valuator) { create(:user, name: "Lorry", email: "test@example.org", organization: organization, created_at: user_creation_date) } - let(:collaborator) { create(:user, organization: organization, created_at: user_creation_date) } - let(:moderator) { create(:user, organization: organization, created_at: user_creation_date) } - - let(:resource_controller) { Decidim::DecidimAwesome::Admin::AdminAccountabilityController } - - let!(:participatory_process_user_role1) { create(:participatory_process_user_role, user: administrator, role: "admin", created_at: 4.days.ago) } - let!(:participatory_process_user_role2) { create(:participatory_process_user_role, user: valuator, role: "valuator", created_at: 3.days.ago) } - let!(:participatory_process_user_role3) { create(:participatory_process_user_role, user: collaborator, role: "collaborator", created_at: 2.days.ago) } - let!(:participatory_process_user_role4) { create(:participatory_process_user_role, user: moderator, role: "moderator", created_at: 1.day.ago) } - let!(:assembly_user_role1) { create(:assembly_user_role, user: administrator, role: "admin", created_at: 4.days.ago) } - let!(:assembly_user_role2) { create(:assembly_user_role, user: valuator, role: "valuator", created_at: 3.days.ago) } - let!(:assembly_user_role3) { create(:assembly_user_role, user: collaborator, role: "collaborator", created_at: 2.days.ago) } - let!(:assembly_user_role4) { create(:assembly_user_role, user: moderator, role: "moderator", created_at: 1.day.ago) } - - include_context "with filterable context" - - before do - # ensure papertrail has the same created_at date as the object being mocked - Decidim::DecidimAwesome::PaperTrailVersion.space_role_actions(organization).map { |v| v.update(created_at: v.item.created_at) } - - switch_to_host(organization.host) - login_as admin, scope: :user - - visit decidim_admin.root_path - - click_link "Participants" - click_link "Admin accountability" - end - - with_versioning do - it "shows filters" do - expect(page).to have_content("Filter") - expect(page).to have_css("#q_user_name_or_user_email_cont") - expect(page).to have_css("#q_created_at_gteq") - expect(page).to have_css("#q_created_at_lteq") - end - - it "displays the filter labels" do - find("a.dropdown").hover - expect(page).to have_content("Participatory space type") - expect(page).to have_content("Role type") - - find("a", text: "Participatory space type").hover - expect(page).to have_content("Participatory processes") - expect(page).to have_content("Assemblies") - - find("a", text: "Role type").hover - expect(page).to have_content("Admin") - expect(page).to have_content("Collaborator") - expect(page).to have_content("Moderator") - expect(page).to have_content("Valuator") - end - - context "when filtering admin_actions by PARTICIPATORY SPACE" do - it "Assemblies space type" do - apply_filter("Participatory space type", "Assemblies") - - within "tbody" do - expect(page).to have_content("Assemblies >", count: 4) - end - end - - it "Processes space type" do - apply_filter("Participatory space type", "Participatory processes") - - within "tbody" do - expect(page).to have_content("Processes >", count: 4) - end - end - - it "exports the result" do - apply_filter("Participatory space type", "Participatory processes") - - find(".exports.dropdown").click - perform_enqueued_jobs { click_link "Export as CSV" } - - within ".callout.success" do - expect(page).to have_content("Export job has been enqueued. You will receive an email when it's ready.") - end - - expect(last_email.subject).to include("Your export", "csv", "is ready") - expect(last_email.attachments.length).to be_positive - expect(last_email.attachments.first.filename).to match(/^admin_actions.*\.zip$/) - expect(current_url).to include(decidim_admin_decidim_awesome.admin_accountability_path) - expect(current_url).not_to include("admins=true") - end - end - - context "when filtering admin_actions by ROLE TYPE" do - it "Admin role type" do - apply_filter("Role type", "Admin") - - within "tbody" do - expect(page).to have_content("Administrator", count: 2) - end - end - - it "Collaborator role type" do - apply_filter("Role type", "Collaborator") - - within "tbody" do - expect(page).to have_content("Collaborator", count: 2) - end - end - - it "Moderator role type" do - apply_filter("Role type", "Moderator") - - within "tbody" do - expect(page).to have_content("Moderator", count: 2) - end - end - - it "Valuator role type" do - apply_filter("Role type", "Valuator") - - within "tbody" do - expect(page).to have_content("Valuator", count: 2) - end - end - end - - context "when searching by name or email" do - it "searches by name" do - search_by_text("Lorry") - - within "tbody" do - expect(page).to have_content("Lorry", count: 2) - end - end - - it "searches by email" do - search_by_text("test@example.org") - - within "tbody" do - expect(page).to have_content("test@example.org", count: 2) - end - end - end - - context "when searching by date" do - def search_by_date(start_date, end_date) - within(".filters__section") do - fill_in(:q_created_at_gteq, with: start_date) if start_date.present? - fill_in(:q_created_at_lteq, with: end_date) if end_date.present? - - find("*[type=submit]").click - end - end - - context "when the start date is earlier" do - it "displays all entries" do - search_by_date(6.days.ago, "") - - within "tbody" do - expect(page).to have_css("tr", count: 8) - end - end - end - - context "when the start date is later" do - it "displays no entries" do - search_by_date(1.day.from_now, "") - - within "tbody" do - expect(page).to have_css("tr", count: 0) - end - end - end - - context "when the end date is later" do - it "displays all entries" do - search_by_date("", 5.days.from_now) - - within "tbody" do - expect(page).to have_css("tr", count: 8) - end - end - end - - context "when the end date is earlier" do - it "displays no entries" do - search_by_date("", 6.days.ago) - - within "tbody" do - expect(page).to have_css("tr", count: 0) - end - end - end - - context "when searching in range" do - it "displays entries in range" do - search_by_date(3.days.ago, 2.days.ago) - - within "tbody" do - expect(page).to have_css("tr", count: 4) - expect(page).to have_content("Collaborator", count: 2) - expect(page).to have_content("Valuator", count: 2) - expect(page).to have_content(collaborator.name, count: 2) - expect(page).to have_content(valuator.name, count: 2) - expect(page).to have_content(participatory_process_user_role2.participatory_space.title["en"]) - expect(page).to have_content(participatory_process_user_role3.participatory_space.title["en"]) - expect(page).to have_content(assembly_user_role2.participatory_space.title["en"]) - expect(page).to have_content(assembly_user_role3.participatory_space.title["en"]) - end - end - end - end - end -end diff --git a/spec/system/admin/admin_accountability_spec.rb b/spec/system/admin/admin_accountability_spec.rb deleted file mode 100644 index c55d8fe..0000000 --- a/spec/system/admin/admin_accountability_spec.rb +++ /dev/null @@ -1,304 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Admin accountability", type: :system do - let(:user_creation_date) { 7.days.ago } - let(:login_date) { 6.days.ago } - let(:organization) { create :organization } - let(:external_organization) { create :organization } - let!(:admin) { create :user, :admin, :confirmed, organization: organization, created_at: 9.days.ago } - let!(:external_admin) { create :user, :admin, :confirmed, organization: external_organization } - - let(:administrator) { create(:user, organization: organization, last_sign_in_at: login_date, created_at: user_creation_date) } - let(:valuator) { create(:user, organization: organization, created_at: user_creation_date) } - let(:collaborator) { create(:user, organization: organization, created_at: user_creation_date) } - let(:moderator) { create(:user, organization: organization, created_at: user_creation_date) } - let(:participatory_process) { create(:participatory_process, organization: organization) } - - let(:external_administrator) { create(:user, organization: external_organization, last_sign_in_at: login_date, created_at: user_creation_date) } - let(:external_valuator) { create(:user, organization: external_organization, created_at: user_creation_date) } - let(:external_collaborator) { create(:user, organization: external_organization, created_at: user_creation_date) } - let(:external_moderator) { create(:user, organization: external_organization, created_at: user_creation_date) } - let(:external_participatory_process) { create(:participatory_process, organization: external_organization) } - - let(:status) { true } - - before do - # rubocop:disable Rails/SkipsModelValidations: - Decidim::DecidimAwesome::PaperTrailVersion.find_by(item: admin)&.update_column(:created_at, admin.created_at) - # rubocop:enable Rails/SkipsModelValidations: - allow(Decidim::DecidimAwesome.config).to receive(:admin_accountability).and_return(status) - switch_to_host(organization.host) - login_as admin, scope: :user - - visit decidim_admin.root_path - end - - context "when admin accountability is enabled" do - it "shows the admin accountability link" do - click_link "Participants" - - expect(page).to have_content("Admin accountability") - end - end - - context "when admin accountability is disabled" do - let(:status) { :disabled } - - it "does not show the admin accountability link" do - click_link "Participants" - - expect(page).not_to have_content("Admin accountability") - end - end - - context "when there are admin role actions" do - before do - create(:participatory_process_user_role, user: administrator, participatory_process: participatory_process, role: "admin", created_at: 4.days.ago) - create(:participatory_process_user_role, user: valuator, participatory_process: participatory_process, role: "valuator", created_at: 3.days.ago) - create(:participatory_process_user_role, user: collaborator, participatory_process: participatory_process, role: "collaborator", created_at: 2.days.ago) - create(:participatory_process_user_role, user: moderator, participatory_process: participatory_process, role: "moderator", created_at: 1.day.ago) - - Decidim::ParticipatoryProcessUserRole.find_by(user: collaborator).destroy - - click_link "Participants" - end - - it "shows the correct information for each user", versioning: true do - click_link "Admin accountability" - - expect(page).not_to have_content("NOTE: This list might not include users created/removed before") - - expect(page).to have_link("Processes > #{participatory_process.title["en"]}", - href: "/admin/participatory_processes/#{participatory_process.slug}/user_roles", count: 4) - - within all("table tr")[1] do - expect(page).to have_content("Moderator") - expect(page).to have_content(moderator.name) - expect(page).to have_content(moderator.email) - expect(page).to have_content(1.day.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - expect(page).not_to have_content(login_date.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Never logged yet") - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - end - - within all("table tr")[2] do - expect(page).to have_content("Collaborator") - expect(page).to have_content(collaborator.name) - expect(page).to have_content(collaborator.email) - expect(page).to have_content(2.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content(login_date.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Never logged yet") - expect(page).to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content("Currently active") - end - - within all("table tr")[3] do - expect(page).to have_content("Valuator") - expect(page).to have_content(valuator.name) - expect(page).to have_content(valuator.email) - expect(page).to have_content(3.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - expect(page).not_to have_content(login_date.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Never logged yet") - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - end - - within all("table tr")[4] do - expect(page).to have_content("Administrator") - expect(page).to have_content(administrator.name) - expect(page).to have_content(administrator.email) - expect(page).to have_content(4.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - expect(page).to have_content(login_date.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content("Never logged yet") - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - end - end - - context "when external organization data is present" do - before do - create(:participatory_process_user_role, user: external_administrator, participatory_process: external_participatory_process, role: "admin", created_at: 4.days.ago) - create(:participatory_process_user_role, user: external_valuator, participatory_process: external_participatory_process, role: "valuator", created_at: 3.days.ago) - create(:participatory_process_user_role, user: external_collaborator, participatory_process: external_participatory_process, role: "collaborator", created_at: 2.days.ago) - create(:participatory_process_user_role, user: external_moderator, participatory_process: external_participatory_process, role: "moderator", created_at: 1.day.ago) - end - - it "does not include the other organization", versioning: true do - click_link "Admin accountability" - - expect(page).to have_link("Processes > #{participatory_process.title["en"]}", - href: "/admin/participatory_processes/#{participatory_process.slug}/user_roles", count: 4) - expect(page).not_to have_link("Processes > #{external_participatory_process.title["en"]}", - href: "/admin/participatory_processes/#{external_participatory_process.slug}/user_roles") - - expect(page).to have_content(administrator.email) - expect(page).to have_content(moderator.email) - expect(page).to have_content(collaborator.email) - expect(page).to have_content(valuator.email) - expect(page).not_to have_content(external_administrator.email) - expect(page).not_to have_content(external_moderator.email) - expect(page).not_to have_content(external_collaborator.email) - expect(page).not_to have_content(external_valuator.email) - end - - context "when visiting the external organization" do - before do - switch_to_host(external_organization.host) - login_as external_admin, scope: :user - visit decidim_admin.root_path - - Decidim::ParticipatoryProcessUserRole.find_by(user: external_collaborator).destroy - - click_link "Participants" - click_link "Admin accountability" - end - - it "shows data only for external_organization", versioning: true do - expect(page).not_to have_link("Processes > #{participatory_process.title["en"]}", - href: "/admin/participatory_processes/#{participatory_process.slug}/user_roles") - expect(page).to have_link("Processes > #{external_participatory_process.title["en"]}", - href: "/admin/participatory_processes/#{external_participatory_process.slug}/user_roles") - expect(page).not_to have_content(administrator.name) - expect(page).not_to have_content(valuator.name) - expect(page).not_to have_content(collaborator.name) - expect(page).not_to have_content(moderator.name) - expect(page).to have_content(external_administrator.name) - expect(page).to have_content(external_valuator.name) - expect(page).to have_content(external_collaborator.name) - expect(page).to have_content(external_moderator.name) - end - end - end - end - - context "when there are multiple assignations for the same user" do - before do - create(:participatory_process_user_role, user: collaborator, participatory_process: participatory_process, role: "collaborator", created_at: 3.days.ago) - - Decidim::ParticipatoryProcessUserRole.find_by(user: collaborator).destroy - - create(:participatory_process_user_role, user: collaborator, participatory_process: participatory_process, role: "valuator", created_at: 2.days.ago) - - Decidim::ParticipatoryProcessUserRole.find_by(user: collaborator).destroy - - create(:participatory_process_user_role, user: collaborator, participatory_process: participatory_process, role: "collaborator", created_at: 1.day.ago) - - click_link "Participants" - click_link "Admin accountability" - end - - it "shows currently active", versioning: true do - within all("table tr")[1] do - expect(page).to have_content("Collaborator") - expect(page).to have_content(collaborator.name) - expect(page).to have_content(collaborator.email) - expect(page).to have_content(1.day.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - end - - within all("table tr")[2] do - expect(page).to have_content("Valuator") - expect(page).to have_content(collaborator.name) - expect(page).to have_content(collaborator.email) - expect(page).to have_content(2.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content("Currently active") - end - - within all("table tr")[3] do - expect(page).to have_content("Collaborator") - expect(page).to have_content(collaborator.name) - expect(page).to have_content(collaborator.email) - expect(page).to have_content(3.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content("Currently active") - end - end - end - - context "when user listed has been removed" do - let(:valuator) { create(:user, :deleted, organization: organization, created_at: user_creation_date) } - - before do - create(:participatory_process_user_role, user: collaborator, participatory_process: participatory_process, role: "collaborator", created_at: 3.days.ago) - collaborator.destroy - create(:participatory_process_user_role, user: valuator, participatory_process: participatory_process, role: "valuator", created_at: 2.days.ago) - - click_link "Participants" - click_link "Admin accountability" - end - - it "shows the user as removed", versioning: true do - within all("table tr")[1] do - expect(page).to have_content("Valuator") - expect(page).to have_content("Deleted user") - expect(page).to have_content(2.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - end - - within all("table tr")[2] do - expect(page).to have_content("Collaborator") - expect(page).to have_content("User not in the database") - expect(page).to have_content(3.days.ago.strftime("%d/%m/%Y %H:%M")) - expect(page).not_to have_content(Time.current.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - end - end - end - - context "when global admins" do - let!(:second_admin) { create(:user, :admin, organization: organization, created_at: 3.days.ago) } - - before do - click_link "Participants" - click_link "Admin accountability" - end - - it "shows the current admins", versioning: true do - click_link "List global admins" - - expect(page).not_to have_content("NOTE: This list might not include users created/removed before") - - expect(page).not_to have_content(external_admin.name) - expect(page).not_to have_content(external_admin.email) - - within all("table tr")[1] do - expect(page).to have_content("Super admin") - expect(page).to have_content(second_admin.name) - expect(page).to have_content(second_admin.email) - expect(page).to have_content("Never logged yet") - expect(page).to have_content(second_admin.created_at.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - end - - within all("table tr")[2] do - expect(page).to have_content("Super admin") - expect(page).to have_content(admin.name) - expect(page).to have_content(admin.email) - expect(page).not_to have_content("Never logged yet") - expect(page).to have_content(admin.created_at.strftime("%d/%m/%Y %H:%M")) - expect(page).to have_content("Currently active") - end - end - - context "when first versioning is newer than the user creation date" do - let(:missing_date) { 8.days.ago } - - before do - # rubocop:disable Rails/SkipsModelValidations: - Decidim::DecidimAwesome::PaperTrailVersion.where(item_type: "Decidim::UserBaseEntity").last.update_column(:created_at, missing_date) - # rubocop:enable Rails/SkipsModelValidations: - end - - it "shows a warning message", versioning: true do - click_link "List global admins" - expect(page).to have_content("NOTE: This list might not include users created/removed before #{missing_date.strftime("%d/%m/%Y %H:%M")}") - end - end - end -end diff --git a/spec/system/admin/admin_edits_proposal_spec.rb b/spec/system/admin/admin_edits_proposal_spec.rb deleted file mode 100644 index 0d92f82..0000000 --- a/spec/system/admin/admin_edits_proposal_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/editor_examples" - -describe "Admin edits proposals", type: :system do - let(:manifest_name) { "proposals" } - let(:organization) { participatory_process.organization } - let!(:user) { create :user, :admin, :confirmed, organization: organization } - let!(:proposal) { create :proposal, :official, component: component } - let!(:allow_images_in_proposals) { create(:awesome_config, organization: organization, var: :allow_images_in_proposals, value: images_in_proposals) } - let!(:allow_images_in_small_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_full_editor, value: images_editor) } - let!(:use_markdown_editor) { create(:awesome_config, organization: organization, var: :use_markdown_editor, value: markdown_enabled) } - let!(:allow_images_in_markdown_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_markdown_editor, value: markdown_images) } - let(:images_in_proposals) { false } - let(:images_editor) { false } - let(:markdown_enabled) { false } - let(:markdown_images) { false } - let(:rte_enabled) { false } - let(:editor_selector) { "#proposal_body_en" } - - include_context "when managing a component as an admin" - - before do - organization.update(rich_text_editor_in_public_views: rte_enabled) - visit_component_admin - - find("a.action-icon--edit-proposal").click - end - - context "when rich text editor is enabled for participants" do - let(:rte_enabled) { true } - - it_behaves_like "has no drag and drop", true - - context "and images in RTE are enabled" do - let(:images_editor) { true } - - it_behaves_like "has drag and drop", true - end - - context "and markdown is enabled" do - let(:markdown_enabled) { true } - - it_behaves_like "has markdown editor" - - context "and images are enabled" do - let(:markdown_images) { true } - - it_behaves_like "has markdown editor", true - end - end - end - - context "when rich text editor is NOT enabled for participants" do - it_behaves_like "has no drag and drop", true - - context "and images in RTE are enabled" do - let(:images_editor) { true } - - it_behaves_like "has drag and drop", true - end - - context "and images in proposals is enabled" do - let(:images_in_proposals) { true } - - it_behaves_like "has no drag and drop", true - end - - context "and markdown is enabled" do - let(:markdown_enabled) { true } - - it_behaves_like "has markdown editor" - end - end - - context "when editing in markdown mode" do - let(:rte_enabled) { true } - let(:markdown_enabled) { true } - let(:text) { "# title\\n\\nParagraph\\nline 2" } - let(:html) { "

title

Paragraph
line 2

" } - - it "converts markdown to html before saving" do - sleep 1 - page.execute_script("$('[name=\"faker-inscrybmde\"]:first')[0].InscrybMDE.value('#{text}')") - - click_button "Update" - - expect(Decidim::Proposals::Proposal.last.body["en"].gsub(/[\n\r]/, "")).to eq(html) - end - end -end diff --git a/spec/system/admin/admin_edits_proposals_custom_fields_spec.rb b/spec/system/admin/admin_edits_proposals_custom_fields_spec.rb deleted file mode 100644 index 464c18f..0000000 --- a/spec/system/admin/admin_edits_proposals_custom_fields_spec.rb +++ /dev/null @@ -1,125 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Admin edits proposals", type: :system do - let(:manifest_name) { "proposals" } - let(:organization) { participatory_process.organization } - let!(:user) { create :user, :admin, :confirmed, organization: organization } - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_bar } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - let(:slug) { participatory_process.slug } - - let(:data) { "[#{data1},#{data2},#{data3}]" } - let(:data1) { '{"type":"text","label":"Full Name","subtype":"text","className":"form-control","name":"text-1476748004559"}' } - let(:data2) { '{"type":"select","label":"Occupation","className":"form-control","name":"select-1476748006618","values":[{"label":"Street Sweeper","value":"option-1","selected":true},{"label":"Moth Man","value":"option-2"},{"label":"Chemist","value":"option-3"}]}' } - let(:data3) { '{"type":"textarea","label":"Short Bio","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - let(:custom_fields) do - { - "foo" => "[#{data1},#{data2}]", - "bar" => "[#{data3}]" - } - end - let!(:proposal) do - create(:proposal, - :official, - component: component, - body: { - en: '
Bio
I shot the sheriff
', - ca: '
Bio
Jo disparo al sheriff
' - }) - end - - include_context "when managing a component as an admin" - - before do - visit_component_admin - - find("a.action-icon--edit-proposal").click - end - - it "displays custom fields" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).to have_content("Short Bio") - expect(page).to have_xpath("//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']") - expect(page).not_to have_css(".form-error.is-visible") - - within "#proposal-body-tabs" do - click_link "Català" - - expect(page).to have_xpath("//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='Jo disparo al sheriff']") - end - end - - context "and there are out of scope" do - let(:custom_fields) do - { - "bar" => "[#{data3}]" - } - end - let(:slug) { "another-slug" } - - it "displays normal proposal editor" do - expect(page).to have_content("Title") - expect(page).to have_content("Body") - expect(page).not_to have_content("Full Name") - expect(page).not_to have_content("Occupation") - expect(page).not_to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - end - end - - context "and some are scoped to other places" do - let(:slug) { "another-slug" } - - it "displays the scoped fields" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - expect(page).not_to have_css(".form-error.is-visible") - end - end - - context "when creating the proposal" do - it "saves the proposal in XML" do - fill_in :proposal_title_en, with: "A far west character" - fill_in :"text-1476748004559", with: "Lucky Luke" - fill_in :"textarea-1476748007461", with: "I shot everything" - - click_button "Update" - - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
Lucky Luke
') - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
I shot everything
') - end - - context "and has multiple languages" do - it "saves the proposal in XML" do - fill_in :proposal_title_en, with: "A far west character" - fill_in :"text-1476748004559", with: "Lucky Luke" - fill_in :"textarea-1476748007461", with: "I shot everything" - - within "#proposal-body-tabs" do - click_link "Català" - end - - fill_in :"text-1476748004559", with: "Lucky Luke" - fill_in :"textarea-1476748007461", with: "Li agrada disparar" - - click_button "Update" - - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
Lucky Luke
') - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
I shot everything
') - expect(Decidim::Proposals::Proposal.last.body["ca"]).to include('
Li agrada disparar
') - end - end - end -end diff --git a/spec/system/admin/admin_manages_menu_overrides_spec.rb b/spec/system/admin/admin_manages_menu_overrides_spec.rb deleted file mode 100644 index 614ae74..0000000 --- a/spec/system/admin/admin_manages_menu_overrides_spec.rb +++ /dev/null @@ -1,177 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/menu_hack_contexts" - -describe "Admin manages hacked menus", type: :system do - let(:organization) { create :organization } - let!(:config) { create :awesome_config, organization: organization, var: menu_name, value: previous_menu } - let!(:user) { create(:user, :admin, :confirmed, organization: organization) } - let!(:participatory_process) { create :participatory_process, organization: organization } - let(:previous_menu) do - [] - end - - include_context "with menu hacks params" - - before do - Decidim::MenuRegistry.register :menu do |menu| - menu.add_item :native_menu, - "Native", - "/some-path?locale=ca", - position: 5 - end - switch_to_host(organization.host) - login_as user, scope: :user - visit decidim_admin_decidim_awesome.menu_hacks_path - end - - after do - Decidim::MenuRegistry.find(:menu).configurations.pop - end - - context "when visiting the index" do - it "shows default menu items" do - within "table tbody" do - expect(page).to have_content("Home") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - end - end - - it "allows to edit a default item" do - within find("tr", text: "Home") do - click_link "Edit" - end - - fill_in "menu_raw_label_en", with: "A new beggining" - find("*[type=submit]").click - - within "table tbody" do - expect(page).to have_content("A new beggining") - expect(page).not_to have_content("Home") - end - end - - it "allows to create a new item" do - click_link "New item" - - fill_in "menu_raw_label_en", with: "Blog" - fill_in "menu_url", with: "http://external.blog" - fill_in "menu_position", with: "1.5" - - find("*[type=submit]").click - - within "table tbody" do - expect(page).to have_content("Home") - expect(page).to have_content("Blog") - expect(page).to have_content("http://external.blog") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - end - end - - context "when native menu has query strings" do - it "allows to edit it" do - within find("tr", text: "Native") do - click_link "Edit" - end - - fill_in "menu_raw_label_en", with: "Native edited" - find("*[type=submit]").click - - within "table tbody" do - expect(page).to have_content("Native edited") - expect(page).to have_content("/some-path") - expect(page).not_to have_content("/some-path?locale=ca") - end - end - end - - context "when menu has overrides" do - include_context "with menu hacks params" - - let(:url) { "/" } - let(:previous_menu) do - [{ "url" => url, "label" => { "en" => "A new beggining" }, "position" => 10 }] - end - - it "shows default and overrides menu items" do - within "table tbody" do - expect(page).to have_content("A new beggining") - expect(page).not_to have_content("Home") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - end - end - - it "can be edited" do - within find("tr", text: "A new beggining") do - click_link "Edit" - end - - fill_in "menu_raw_label_en", with: "Another thing" - find("*[type=submit]").click - - within "table tbody" do - expect(page).to have_content("Another thing") - expect(page).not_to have_content("A new beggining") - expect(page).not_to have_content("Home") - end - end - - it "can be deleted" do - within find("tr", text: "A new beggining") do - accept_confirm { click_link "Remove customization" } - end - - within "table tbody" do - expect(page).to have_content("Home") - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when menu has new items" do - include_context "with menu hacks params" - - let(:url) { "/a-new-link" } - let(:previous_menu) do - [{ "url" => url, "label" => { "en" => "A new link" }, "position" => 10 }] - end - - it "shows default and overrides menu items" do - within "table tbody" do - expect(page).to have_content("Home") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - expect(page).to have_content("A new link") - end - end - - it "can be edited" do - within find("tr", text: "A new link") do - click_link "Edit" - end - - fill_in "menu_raw_label_en", with: "Another thing" - find("*[type=submit]").click - - within "table tbody" do - expect(page).to have_content("Another thing") - expect(page).not_to have_content("A new link") - end - end - - it "can be deleted" do - within find("tr", text: "A new link") do - accept_confirm { click_link "Remove addition" } - end - - within "table tbody" do - expect(page).not_to have_content("A new link") - end - end - end - end -end diff --git a/spec/system/admin/admin_manages_proposal_custom_fields_spec.rb b/spec/system/admin/admin_manages_proposal_custom_fields_spec.rb deleted file mode 100644 index 96b9221..0000000 --- a/spec/system/admin/admin_manages_proposal_custom_fields_spec.rb +++ /dev/null @@ -1,192 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/box_label_editor" - -describe "Admin manages custom proposal fields", type: :system do - let(:organization) { create :organization } - let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } - let(:custom_fields) do - {} - end - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_bar } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes", component_manifest: "proposals" }) } - let!(:another_constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes" }) } - - let(:data) { "[#{data1},#{data2},#{data3}]" } - let(:data1) { '{"type":"text","label":"Full Name","subtype":"text","className":"form-control","name":"text-1476748004559"}' } - let(:data2) { '{"type":"select","label":"Occupation","className":"form-control","name":"select-1476748006618","values":[{"label":"Street Sweeper","value":"option-1","selected":true},{"label":"Moth Man","value":"option-2"},{"label":"Chemist","value":"option-3"}]}' } - let(:data3) { '{"type":"textarea","label":"Short Bio","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - before do - switch_to_host(organization.host) - login_as admin, scope: :user - visit decidim_admin_decidim_awesome.config_path(:proposal_custom_fields) - end - - context "when creating a new box" do - it "saves the content" do - click_link 'Add a new "custom fields" box' - - expect(page).to have_admin_callout("created successfully") - - sleep 2 - # page.execute_script("$('.proposal_custom_fields_editor:first')[0].FormBuilder.actions.setData(#{data})") - page.execute_script("document.querySelector('.proposal_custom_fields_editor').FormBuilder.actions.setData(#{data})") - - find("*[type=submit]").click - - sleep 2 - expect(page).to have_admin_callout("updated successfully") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).to have_content("Short Bio") - end - end - - context "when updating new box" do - let(:data) { "[#{data1},#{data3}]" } - let(:custom_fields) do - { - "foo" => "[#{data1},#{data2}]", - "bar" => "[]" - } - end - - it "updates the content" do - sleep 2 - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - - page.execute_script("$('.proposal_custom_fields_container[data-key=\"foo\"] .proposal_custom_fields_editor')[0].FormBuilder.actions.setData(#{data})") - find("*[type=submit]").click - - sleep 2 - expect(page).to have_admin_callout("updated successfully") - expect(page).to have_content("Full Name") - expect(page).not_to have_content("Occupation") - expect(page).not_to have_content("Street Sweeper") - expect(page).to have_content("Short Bio") - end - - it_behaves_like "edits box label inline", :fields, :foo - - context "when removing a box" do - let(:custom_fields) do - { - "foo" => "[#{data1}]", - "bar" => "[#{data2}]" - } - end - - it "updates the content" do - sleep 2 - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - - within ".proposal_custom_fields_container[data-key=\"foo\"]" do - accept_confirm { click_link 'Remove this "custom fields" box' } - end - - sleep 2 - expect(page).to have_admin_callout("removed successfully") - expect(page).not_to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_foo)).not_to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar)).to be_present - end - end - - context "when adding a constraint" do - let(:custom_fields) do - { - "foo" => "[#{data1}]", - "bar" => "[#{data2}]" - } - end - - it "adds a new config helper var" do - within ".proposal_custom_fields_container[data-key=\"foo\"]" do - click_link "Add case" - end - - select "Processes", from: "constraint_participatory_space_manifest" - within ".modal-content" do - find("*[type=submit]").click - end - - sleep 2 - - within ".proposal_custom_fields_container[data-key=\"foo\"] .constraints-editor" do - expect(page).to have_content("Processes") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar).constraints.first.settings).to eq(constraint.settings) - end - - context "when removing a constraint" do - let(:custom_fields) do - { - "foo" => "[#{data1}]", - "bar" => "[#{data2}]" - } - end - - it "removes the helper config var" do - within ".proposal_custom_fields_container[data-key=\"bar\"] .constraints-editor" do - expect(page).to have_content("Processes") - expect(page).to have_content("Proposals") - end - - within ".proposal_custom_fields_container[data-key=\"bar\"]" do - within first(".constraints-list li") do - click_link "Delete" - end - end - - within ".proposal_custom_fields_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Proposals") - end - - visit decidim_admin_decidim_awesome.config_path(:proposal_custom_fields) - - within ".proposal_custom_fields_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Proposals") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar).constraints.count).to eq(1) - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar).constraints.first).to eq(another_constraint) - end - - context "and there is only one constraint" do - let!(:another_constraint) { nil } - - it "do not remove the helper config var" do - within ".proposal_custom_fields_container[data-key=\"bar\"]" do - click_link "Delete" - end - - within ".proposal_custom_fields_container[data-key=\"bar\"] .constraints-editor" do - expect(page).to have_content("Proposals") - end - - expect(page).to have_content("Sorry, this cannot be deleted") - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar).constraints.count).to eq(1) - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :proposal_custom_field_bar).constraints.first).to eq(constraint) - end - end - end - end - end -end diff --git a/spec/system/admin/admin_manages_scoped_admins_spec.rb b/spec/system/admin/admin_manages_scoped_admins_spec.rb deleted file mode 100644 index c8dff6c..0000000 --- a/spec/system/admin/admin_manages_scoped_admins_spec.rb +++ /dev/null @@ -1,156 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/box_label_editor" - -describe "Admin manages scoped admins", type: :system do - let(:organization) { create :organization } - let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } - let!(:user) { create(:user, :confirmed, organization: organization) } - let!(:user2) { create(:user, :confirmed, organization: organization) } - let!(:user3) { create(:user, :confirmed, organization: organization) } - let(:admins) do - {} - end - let!(:config) { create :awesome_config, organization: organization, var: :scoped_admins, value: admins } - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_admin_bar } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes" }) } - - before do - switch_to_host(organization.host) - login_as admin, scope: :user - visit decidim_admin_decidim_awesome.config_path(:admins) - end - - context "when creating a new box" do - it "saves the content" do - click_link 'Add a new "Scoped Admins" group' - - expect(page).to have_admin_callout("created successfully") - - expect(page).not_to have_content(user.name.to_s) - sleep 1 - page.execute_script("$('.multiusers-select:first').append(new Option('#{user.name}', #{user.id}, true, true)).trigger('change');") - - find("*[type=submit]").click - - expect(page).to have_admin_callout("updated successfully") - expect(page).to have_content(user.name.to_s) - end - end - - shared_examples "saves content" do |_key| - it "updates succesfully" do - expect(page).not_to have_content(user.name.to_s) - expect(page).to have_content(user2.name.to_s) - expect(page).to have_content(user3.name.to_s) - - sleep 1 - page.execute_script("$('.multiusers-select:first').append(new Option('#{user.name}', #{user.id}, true, true)).trigger('change');") - find("*[type=submit]").click - - expect(page).to have_admin_callout("updated successfully") - expect(page).to have_content(user.name.to_s) - expect(page).to have_content(user.name.to_s) - expect(page).to have_content(user3.name.to_s) - end - end - - context "when updating new box" do - let(:admins) do - { - "foo" => [user2.id.to_s], - "bar" => [user3.id.to_s] - } - end - - it_behaves_like "saves content", "foo" - - it_behaves_like "edits box label inline", :admins, :foo - - context "when removing a box" do - let(:admins) do - { - "foo" => [user2.id.to_s], - "bar" => [user3.id.to_s] - } - end - - it "updates the content" do - expect(page).to have_content(user2.name.to_s) - expect(page).to have_content(user3.name.to_s) - - within ".scoped_admins_container[data-key=\"foo\"]" do - accept_confirm { click_link 'Remove this "Scoped Admins" group' } - end - - expect(page).to have_admin_callout("removed successfully") - expect(page).to have_content(user3.name.to_s) - expect(page).not_to have_content(user2.name.to_s) - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_foo)).not_to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_bar)).to be_present - end - end - - context "when adding a constraint" do - let(:admins) do - { - "foo" => [user2.id.to_s], - "bar" => [user3.id.to_s] - } - end - - it "adds a new config helper var" do - within ".scoped_admins_container[data-key=\"foo\"]" do - click_link "Add case" - end - - select "Processes", from: "constraint_participatory_space_manifest" - within ".modal-content" do - find("*[type=submit]").click - end - - sleep 2 - - within ".scoped_admins_container[data-key=\"foo\"] .constraints-editor" do - expect(page).to have_content("Processes") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_bar).constraints.first.settings).to eq("participatory_space_manifest" => "participatory_processes") - end - - context "when removing a constraint" do - let(:admins) do - { - "foo" => [user2.id.to_s], - "bar" => [user3.id.to_s] - } - end - - it "removes the helper config var" do - within ".scoped_admins_container[data-key=\"bar\"] .constraints-editor" do - expect(page).to have_content("Processes") - end - - within ".scoped_admins_container[data-key=\"bar\"]" do - click_link "Delete" - end - - within ".scoped_admins_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Processes") - end - - visit decidim_admin_decidim_awesome.config_path(:admins) - - within ".scoped_admins_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Processes") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_admin_bar).constraints).not_to be_present - end - end - end - end -end diff --git a/spec/system/admin/admin_manages_scoped_styles_spec.rb b/spec/system/admin/admin_manages_scoped_styles_spec.rb deleted file mode 100644 index 92895cb..0000000 --- a/spec/system/admin/admin_manages_scoped_styles_spec.rb +++ /dev/null @@ -1,165 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/box_label_editor" - -describe "Admin manages scoped styles", type: :system do - let(:organization) { create :organization } - let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } - let(:styles) do - {} - end - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: styles } - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_style_bar } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes" }) } - - before do - switch_to_host(organization.host) - login_as admin, scope: :user - visit decidim_admin_decidim_awesome.config_path(:styles) - end - - context "when creating a new box" do - it "saves the content in the hash" do - click_link "Add a new CSS box" - - expect(page).to have_admin_callout("created successfully") - - sleep 1 - page.execute_script('document.querySelector(".CodeMirror").CodeMirror.setValue("body {background: red;}");') - - find("*[type=submit]").click - - expect(page).to have_admin_callout("updated successfully") - expect(page).to have_content("body {background: red;}") - end - end - - shared_examples "saves content" do |key| - it "updates succesfully" do - expect(page).to have_content("body {background: red;}") - expect(page).to have_content("body {background: blue;}") - - sleep 1 - page.execute_script("document.querySelector(\"[data-key=#{key}] .CodeMirror\").CodeMirror.setValue(\"body {background: green;}\");") - find("*[type=submit]").click - - expect(page).to have_admin_callout("updated successfully") - expect(page).not_to have_content("body {background: red;}") - expect(page).to have_content("body {background: green;}") - expect(page).to have_content("body {background: blue;}") - end - - it "shows error message if invalid" do - sleep 1 - page.execute_script("document.querySelector(\"[data-key=#{key}] .CodeMirror\").CodeMirror.setValue(\"I am invalid CSS\");") - find("*[type=submit]").click - - expect(page).to have_admin_callout("Error updating configuration! CSS in box ##{key} is invalid") - expect(page).not_to have_content("body {background: red;}") - expect(page).to have_content("body {background: blue;}") - expect(page).to have_content("I am invalid CSS") - within ".scoped_styles_container[data-key=\"#{key}\"] .form-error" do - expect(page).to have_content("Error: Invalid CSS ") - end - end - end - - context "when updating new box" do - let(:styles) do - { - "foo" => "body {background: red;}", - "bar" => "body {background: blue;}" - } - end - - it_behaves_like "saves content", "foo" - - it_behaves_like "edits box label inline", :css, :foo - - context "when removing a box" do - let(:styles) do - { - "foo" => "body {background: red;}", - "bar" => "body {background: blue;}" - } - end - - it "updates the content in the hash" do - expect(page).to have_content("body {background: red;}") - expect(page).to have_content("body {background: blue;}") - - within ".scoped_styles_container[data-key=\"foo\"]" do - accept_confirm { click_link "Remove this CSS box" } - end - - expect(page).to have_admin_callout("removed successfully") - expect(page).to have_content("body {background: blue;}") - expect(page).not_to have_content("body {background: red;}") - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_foo)).not_to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_bar)).to be_present - end - end - - context "when adding a constraint" do - let(:styles) do - { - "foo" => "body {background: red;}", - "bar" => "body {background: blue;}" - } - end - - it "adds a new config helper var" do - within ".scoped_styles_container[data-key=\"foo\"]" do - click_link "Add case" - end - - select "Processes", from: "constraint_participatory_space_manifest" - within ".modal-content" do - find("*[type=submit]").click - end - - sleep 2 - - within ".scoped_styles_container[data-key=\"foo\"] .constraints-editor" do - expect(page).to have_content("Processes") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_bar).constraints.first.settings).to eq("participatory_space_manifest" => "participatory_processes") - end - - context "when removing a constraint" do - let(:styles) do - { - "foo" => "body {background: red;}", - "bar" => "body {background: blue;}" - } - end - - it "removes the helper config var" do - within ".scoped_styles_container[data-key=\"bar\"] .constraints-editor" do - expect(page).to have_content("Processes") - end - - within ".scoped_styles_container[data-key=\"bar\"]" do - click_link "Delete" - end - - within ".scoped_styles_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Processes") - end - - visit decidim_admin_decidim_awesome.config_path(:styles) - - within ".scoped_styles_container[data-key=\"bar\"] .constraints-editor" do - expect(page).not_to have_content("Processes") - end - - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_bar)).to be_present - expect(Decidim::DecidimAwesome::AwesomeConfig.find_by(organization: organization, var: :scoped_style_bar).constraints).not_to be_present - end - end - end - end -end diff --git a/spec/system/admin/admin_spec.rb b/spec/system/admin/admin_spec.rb deleted file mode 100644 index 6f100c1..0000000 --- a/spec/system/admin/admin_spec.rb +++ /dev/null @@ -1,291 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" - -describe "Visit the admin page", type: :system do - let(:organization) { create :organization, rich_text_editor_in_public_views: rte_enabled } - let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } - let(:rte_enabled) { true } - let(:disabled_features) { [] } - let(:version_original) { Decidim.version } - let(:version) { version_original } - - before do - allow(Decidim).to receive(:version).and_return(version) - disabled_features.each do |feature| - allow(Decidim::DecidimAwesome.config).to receive(feature).and_return(:disabled) - end - - switch_to_host(organization.host) - login_as admin, scope: :user - visit decidim_admin.root_path - click_link "Decidim awesome" - end - - it_behaves_like "javascript config vars" - - context "when manages tweaks" do - it "renders the admin page" do - expect(page).to have_content("Decidim Awesome") - end - end - - context "when visiting system compatibility" do - before do - click_link "System Compatibility" - end - - it "renders the page" do - expect(page).to have_content(/System Compatibility Checks/i) - expect(page).not_to have_xpath("//span[@class='text-alert']") - expect(page).to have_xpath("//span[@class='text-success']") - end - - context "and header is overriden" do - let(:version) { "0.11" } - - it "detects missing css" do - expect(page).to have_xpath("//span[@class='text-alert']", count: 1) - end - end - end - - context "when visiting editor hacks" do - context "when editor hacks are enabled" do - before do - click_link "Editor Hacks" - end - - it_behaves_like "has menu link", "editors" - - it "renders the page" do - expect(page).to have_content(/Tweaks for editors/i) - end - end - - context "when editor hacks are disabled" do - let(:disabled_features) do - [:allow_images_in_full_editor, :allow_images_in_small_editor, :use_markdown_editor, - :allow_images_in_markdown_editor] - end - - it_behaves_like "do not have menu link", "editors" - end - end - - context "when visiting surveys hacks" do - context "when survey hacks are enabled" do - before do - click_link "Surveys & Forms" - end - - it_behaves_like "has menu link", "surveys" - - it "renders the page" do - expect(page).to have_content(/Tweaks for surveys/i) - end - end - - context "when survey hacks are disabled" do - let(:disabled_features) { [:auto_save_forms] } - - it_behaves_like "do not have menu link", "surveys" - end - end - - context "when visiting proposal hacks" do - context "when proposal hacks are enabled" do - before do - click_link "Proposals Hacks" - end - - it_behaves_like "has menu link", "proposals" - - it "renders the page" do - expect(page).to have_content(/Tweaks for proposals/i) - expect(page).to have_content("Customize sorting options for the proposals list") - expect(page).to have_content("\"Rich text editor for participants\" is enabled") - expect(page).to have_content("User input validations for the \"title\" field") - expect(page).to have_content("User input validations for the \"body\" field") - end - - context "and additional_proposal_sortings is disabled" do - let(:disabled_features) { [:additional_proposal_sortings] } - - it "renders the page" do - expect(page).not_to have_content("Customize sorting options for the proposals list") - end - end - - context "and rich text editor for participants is disabled" do - let(:rte_enabled) { false } - - it "renders the page" do - expect(page).to have_content(/Tweaks for proposals/i) - expect(page).not_to have_content("\"Rich text editor for participants\" is enabled") - end - end - - context "when all title validators are disabled" do - let(:disabled_features) { [:validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps] } - - it "does not show title options" do - expect(page).not_to have_content("User input validations for the \"title\" field") - expect(page).to have_content("User input validations for the \"body\" field") - end - end - - context "when all body validators are disabled" do - let(:disabled_features) { [:validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps] } - - it "does not show body options" do - expect(page).to have_content("User input validations for the \"title\" field") - expect(page).not_to have_content("User input validations for the \"body\" field") - end - end - end - - context "when some proposals hacks are disabled" do - [:allow_images_in_proposals, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps].each do |var| - let(:disabled_features) { [var] } - - it_behaves_like "has menu link", "proposals" - end - end - - context "when all proposals hacks are disabled" do - let(:disabled_features) { [:allow_images_in_proposals, :validate_title_min_length, :validate_title_max_caps_percent, :validate_title_max_marks_together, :validate_title_start_with_caps, :validate_body_min_length, :validate_body_max_caps_percent, :validate_body_max_marks_together, :validate_body_start_with_caps] } - - it_behaves_like "do not have menu link", "proposals" - end - end - - context "when visiting live chat" do - context "when livechat hacks are enabled" do - before do - click_link "Live Chat" - end - - it_behaves_like "has menu link", "livechat" - - it "renders the page" do - expect(page).to have_content(/Tweaks for livechat/i) - end - end - - context "when livechat hacks are disabled" do - let(:disabled_features) { [:intergram_for_admins, :intergram_for_public] } - - it_behaves_like "do not have menu link", "livechat" - end - end - - context "when visiting CSS tweaks" do - context "when scoped styles are enabled" do - before do - click_link "Custom Styles" - end - - it_behaves_like "has menu link", "styles" - - it "renders the page" do - expect(page).to have_content(/Tweaks for styles/i) - end - end - - context "when scoped styles are disabled" do - let(:disabled_features) { [:scoped_styles] } - - it_behaves_like "do not have menu link", "styles" - end - end - - context "when visiting Menu hacks" do - context "when menu_hacks are enabled" do - before do - click_link "Menu Tweaks" - end - - it_behaves_like "has menu link", "menu_hacks" do - let(:prefix) { "" } - end - - it "renders the page" do - expect(page).to have_content(/Main menu/i) - end - end - - context "when menu_hacks are disabled" do - let(:disabled_features) { [:menu] } - - it_behaves_like "do not have menu link", "menu_hacks" do - let(:prefix) { "" } - end - end - end - - context "when visiting custom redirections" do - context "when custom_redirections are enabled" do - before do - click_link "Custom Redirections" - end - - it_behaves_like "has menu link", "custom_redirects" do - let(:prefix) { "" } - end - - it "renders the page" do - expect(page).to have_content(/Custom redirections/i) - end - end - - context "when custom redirections are disabled" do - let(:disabled_features) { [:custom_redirects] } - - it_behaves_like "do not have menu link", "custom_redirects" - end - end - - context "when visiting Scoped Admins" do - context "when menu_hacks are enabled" do - before do - click_link "Scoped Admins" - end - - it_behaves_like "has menu link", "admins" - - it "renders the page" do - expect(page).to have_content(/Tweaks for admins/i) - end - end - - context "when scoped admins are disabled" do - let(:disabled_features) { [:scoped_admins] } - - it_behaves_like "do not have menu link", "admins" - end - end - - context "when visiting proposal custom fields" do - context "when custom fields are enabled" do - before do - click_link "Proposals Custom Fields" - end - - it_behaves_like "has menu link", "proposal_custom_fields" - - it "renders the page" do - expect(page).to have_content(/Tweaks for proposal_custom_fields/i) - end - end - - context "when custom fields are disabled" do - let(:disabled_features) do - [:proposal_custom_fields] - end - - it_behaves_like "do not have menu link", "proposal_custom_fields" - end - end -end diff --git a/spec/system/admin/scoped_admins_spec.rb b/spec/system/admin/scoped_admins_spec.rb deleted file mode 100644 index 5c713c9..0000000 --- a/spec/system/admin/scoped_admins_spec.rb +++ /dev/null @@ -1,157 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/scoped_admins_examples" - -describe "Scoped admin journeys", type: :system do - let(:organization) { create :organization } - let!(:assembly) { create(:assembly, organization: organization) } - let!(:component) { create(:proposal_component, participatory_space: assembly) } - let!(:proposal) { create(:proposal, :official, component: component) } - let!(:another_component) { create(:meeting_component, participatory_space: assembly) } - let!(:another_assembly) { create(:assembly, organization: organization) } - let!(:participatory_process) { create(:participatory_process, organization: organization) } - let!(:process_group) { create(:participatory_process_group, organization: organization) } - let!(:another_process_group) { create(:participatory_process_group, organization: organization) } - let!(:user) { create(:user, :confirmed, organization: organization) } - let!(:user_accepted) { create(:user, :confirmed, :admin_terms_accepted, organization: organization) } - let!(:admin) { create(:user, :confirmed, :admin, organization: organization) } - let!(:config) { create :awesome_config, organization: organization, var: :scoped_admins, value: admins } - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_admin_bar, value: nil } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: settings) } - let(:admins) do - { - "bar" => [] - } - end - let(:settings) do - {} - end - - before do - # ErrorController is only called when in production mode - unless ENV["SHOW_EXCEPTIONS"] - allow(Rails.application).to \ - receive(:env_config).with(no_args).and_wrap_original do |m, *| - m.call.merge( - "action_dispatch.show_exceptions" => true, - "action_dispatch.show_detailed_exceptions" => false - ) - end - end - - component.update!(default_step_settings: { creation_enabled: true }) - another_component.update!(default_step_settings: { creation_enabled: true }) - switch_to_host(organization.host) - login_as user, scope: :user - end - - context "when is not a scoped admin" do - it_behaves_like "a 404 page" do - let(:target_path) { decidim_admin.root_path } - end - end - - context "when is a scoped admin" do - let(:admins) do - { - "bar" => [user.id.to_s] - } - end - - context "and scope is 'none'" do - let(:settings) do - { - "participatory_space_manifest" => "none" - } - end - - it_behaves_like "a 404 page" do - let(:target_path) { decidim_admin.root_path } - end - end - - context "and admin terms not accepted" do - it "allows admin terms to be accepted" do - welcome_text = "Welcome to the Admin Panel." - welcome_text = "Welcome to the Decidim Admin Panel." if legacy_version? - visit decidim_admin.root_path - - expect(page).to have_content("Agree to the terms and conditions of use") - - click_button "I agree with the terms" - - expect(page).to have_content(welcome_text) - expect(page).not_to have_content("Review them now") - end - end - - context "and admin terms are accepted" do - let(:user) { user_accepted } - - it_behaves_like "allows all admin routes" - it_behaves_like "allows external accesses" - it_behaves_like "forbids awesome access" - it_behaves_like "edits all assemblies" - - context "and there's constraints" do - let(:settings) do - { - "participatory_space_manifest" => "assemblies", - "participatory_space_slug" => assembly.slug - } - end - - it_behaves_like "allows scoped admin routes" - it_behaves_like "shows partial admin links in the frontend" - it_behaves_like "edits allowed assemblies" - - context "and user is a real admin" do - let(:user) { admin } - - it_behaves_like "allows all admin routes" - it_behaves_like "allows external accesses" - it_behaves_like "allows awesome access" - it_behaves_like "edits all assemblies" - end - - context "and scoped to a component" do - let(:settings) do - { - "participatory_space_manifest" => "assemblies", - "participatory_space_slug" => assembly.slug, - "component_manifest" => "proposals" - } - end - - it_behaves_like "allows scoped admin routes" - it_behaves_like "shows component partial admin links in the frontend" - it_behaves_like "edits allowed components" - end - - context "and scoped to aany process group" do - let(:settings) do - { - "participatory_space_manifest" => "process_groups" - } - end - - it_behaves_like "allows access to group processes" - it_behaves_like "allows edit any group process" - end - - context "and scoped to a specfic processes group" do - let(:settings) do - { - "participatory_space_manifest" => "process_groups", - "participatory_space_slug" => process_group.id - } - end - - it_behaves_like "allows access to group processes" - it_behaves_like "allows edit only allowed group process" - end - end - end - end -end diff --git a/spec/system/awesome_intergram_spec.rb b/spec/system/awesome_intergram_spec.rb deleted file mode 100644 index 41e5aa6..0000000 --- a/spec/system/awesome_intergram_spec.rb +++ /dev/null @@ -1,141 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Show intergram chat", type: :system do - let!(:user) { create :user, :confirmed, organization: organization } - let(:organization) { create :organization, available_locales: [:en] } - - let(:intergram_url) { "http://example.com/widget.js" } - let(:intergram_for_admins) { true } - let(:intergram_for_public) { true } - let(:require_login) { false } - let!(:config_public) { create(:awesome_config, organization: organization, var: :intergram_for_public, value: intergram_for_public) } - let!(:config_admins) { create(:awesome_config, organization: organization, var: :intergram_for_admins, value: intergram_for_admins) } - let!(:config_public_settings) { create(:awesome_config, organization: organization, var: :intergram_for_public_settings, value: settings) } - let!(:config_admins_settings) { create(:awesome_config, organization: organization, var: :intergram_for_admins_settings, value: settings) } - let(:settings) do - { - chat_id: "some-id", - require_login: require_login, - color: "some-color", - use_floating_button: true, - title_closed: "title-closed", - title_open: "title-open", - intro_message: "intro-message", - auto_response: "auto-response", - auto_no_response: "auto-no-response" - } - end - - before do - stub_request(:get, /example\.com/).to_return(status: 200, body: "") - Decidim::DecidimAwesome.config.intergram_url = intergram_url - - switch_to_host(organization.host) - visit decidim.root_path - end - - shared_examples "shows the chat" do |logged| - it "has the script tag" do - expect(page).to have_xpath("//script[@src='#{intergram_url}']", visible: :all) - end - - it "has customized variables" do - expect(page.body).to have_content('window.intergramId = "some-id";') - end - - it "variables have been initialized" do - expect(page.execute_script("return window.intergramId")).to eq("some-id") - expect(page.execute_script("return window.intergramCustomizations.titleClosed")).to eq(settings[:title_closed]) - expect(page.execute_script("return window.intergramCustomizations.titleOpen")).to eq(settings[:title_open]) - expect(page.execute_script("return window.intergramCustomizations.introMessage")).to eq(settings[:intro_message]) - expect(page.execute_script("return window.intergramCustomizations.autoResponse")).to eq(settings[:auto_response]) - expect(page.execute_script("return window.intergramCustomizations.autoNoResponse")).to eq(settings[:auto_no_response]) - end - - it "sets visitor name" do - if logged - expect(page.execute_script("return window.intergramOnOpen.visitorName")).to eq(user.nickname) - else - expect(page.execute_script("return window.intergramOnOpen.visitorName")).to eq("") - end - end - end - - shared_examples "do not show the chat" do - it "do not have the script tag" do - expect(page).not_to have_xpath("//script[@src='#{intergram_url}']", visible: :all) - end - - it "has no customized variables" do - expect(page.body).not_to have_content('window.intergramId = "some-id";') - end - - it "no variables are initialized" do - expect(page.execute_script("return window.intergramId")).to be_nil - end - end - - it_behaves_like "shows the chat", false - - if legacy_version? - it "has the script tag in the head" do - expect(page).to have_xpath("//head/script[@src='#{intergram_url}']", visible: :all) - end - else - it "has the script tag in the body" do - expect(page).to have_xpath("//body/script[@src='#{intergram_url}']", visible: :all) - end - end - - context "when login is required" do - let(:require_login) { true } - - it_behaves_like "do not show the chat" - - context "and user is logged in" do - before do - login_as user, scope: :user - visit decidim.root_path - end - - it_behaves_like "shows the chat", true - end - end - - context "when public chat is disabled" do - let(:intergram_for_public) { false } - - it_behaves_like "do not show the chat" - - context "and user is logged in" do - before do - login_as user, scope: :user - visit decidim.root_path - end - - it_behaves_like "do not show the chat" - end - end - - context "when is and admin" do - let!(:user) { create(:user, :admin, :confirmed, organization: organization) } - - before do - login_as user, scope: :user - visit decidim_admin.root_path - end - - it_behaves_like "shows the chat", true - it "has the script tag in the head" do - expect(page).to have_xpath("//head/script[@src='#{intergram_url}']", visible: :all) - end - - context "and admin chat is disabled" do - let(:intergram_for_admins) { false } - - it_behaves_like "do not show the chat" - end - end -end diff --git a/spec/system/awesome_map/awesome_map_spec.rb b/spec/system/awesome_map/awesome_map_spec.rb deleted file mode 100644 index cea574d..0000000 --- a/spec/system/awesome_map/awesome_map_spec.rb +++ /dev/null @@ -1,168 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Show awesome map", type: :system do - include_context "with a component" - let(:manifest_name) { "awesome_map" } - - let!(:proposal_component) { create(:proposal_component, :with_amendments_enabled, :with_geocoding_enabled, participatory_space: participatory_process) } - let!(:proposal) { create(:proposal, component: proposal_component, latitude: 40, longitude: 2) } - let(:emendation) { build(:proposal, component: proposal_component, latitude: 42, longitude: 4) } - let!(:proposal_amendment) { create(:proposal_amendment, amendable: proposal, emendation: emendation) } - let!(:accepted_proposal) { create(:proposal, :accepted, title: { en: "Accepted proposal" }, component: proposal_component, latitude: 40, longitude: -50) } - let!(:evaluating_proposal) { create(:proposal, :evaluating, title: { en: "Evaluating proposal" }, component: proposal_component, latitude: 30, longitude: 45) } - let!(:not_answered_proposal) { create(:proposal, :not_answered, title: { en: "Not answered proposal" }, component: proposal_component, latitude: 70, longitude: 6) } - let!(:null_state_proposal) { create(:proposal, state: nil, title: { en: "Null state proposal" }, component: proposal_component, latitude: 50, longitude: 10) } - let!(:withdrawn_proposal) { create(:proposal, :withdrawn, title: { en: "Withdrawn proposal" }, component: proposal_component, latitude: 60, longitude: -30) } - let!(:rejected_proposal) { create(:proposal, :rejected, title: { en: "Rejected proposal" }, component: proposal_component, latitude: 10, longitude: 80) } - let!(:category) { create(:category, participatory_space: participatory_process) } - let!(:subcategory) { create(:subcategory, parent: category, participatory_space: participatory_process) } - let!(:user) { create :user, :confirmed, organization: organization } - let(:active_step_id) { component.participatory_space.active_step.id } - let(:settings) do - { - menu_amendments: show_amendments, - menu_meetings: show_meetings - } - end - - let(:step_settings) do - { - show_accepted: show_accepted, - show_evaluating: show_evaluating, - show_rejected: show_rejected, - show_withdrawn: show_withdrawn, - show_not_answered: show_not_answered - } - end - let(:show_accepted) { true } - let(:show_evaluating) { true } - let(:show_rejected) { true } - let(:show_withdrawn) { true } - let(:show_not_answered) { true } - - let(:show_amendments) { true } - let(:show_meetings) { true } - let(:map_config) do - { - provider: :osm, - # api_key: "foo", - # static: { url: "https://image.maps.ls.hereapi.com/mia/1.6/mapview" } - dynamic: { - tile_layer: { - url: "http://#{organization.host}:#{Capybara.current_session.server.port}/tile-0.png" - } - } - } - end - - before do - allow(Decidim.config).to receive(:maps).and_return(map_config) - component.update!(step_settings: { active_step_id => step_settings }) - visit_component - end - - it "shows the map" do - within ".wrapper" do - expect(page).not_to have_content("maximum complexity") - expect(page).to have_selector(".awesome-map") - expect(page).to have_selector("#awesome-map") - errors = if legacy_version? - page.driver.browser.manage.logs.get(:browser) - else - page.driver.browser.logs.get(:browser) - end - - errors.each do |error| - expect(error.message).not_to include("map.js"), error.message if error.level == "SEVERE" - end - end - end - - it "has AwesomeMap javascript and CSS" do - within "head", visible: :all do - expect(page).to have_xpath("//link[@rel='stylesheet'][contains(@href,'decidim_decidim_awesome_map')]", visible: :all) - expect(page).to have_xpath("//link[@rel='stylesheet'][contains(@href,'decidim_map')]", visible: :all) - end - within(legacy_version? ? "head" : ".wrapper", visible: :all) do - expect(page).to have_xpath("//script[contains(@src,'decidim_decidim_awesome_map')]", visible: :all) - expect(page).to have_xpath("//script[contains(@src,'decidim_map')]", visible: :all) - end - end - - it "shows categories and colors" do - within ".awesome-map" do - expect(page.body).to have_content(".awesome_map-category_#{category.id}") - expect(page.body).to have_content(".awesome_map-category_#{subcategory.id}") - end - end - - context "when step settings are all true" do - it "shows all proposals markers" do - sleep(3) - expect(page.body).to have_selector("div[title='#{accepted_proposal.title["en"]}']") - expect(page.body).to have_selector("div[title='#{evaluating_proposal.title["en"]}']") - expect(page.body).to have_selector("div[title='#{rejected_proposal.title["en"]}']") - expect(page.body).to have_selector("div[title='#{withdrawn_proposal.title["en"]}']") - expect(page.body).to have_selector("div[title='#{null_state_proposal.title["en"]}']") - end - end - - context "when step settings are all false" do - let(:show_accepted) { false } - let(:show_evaluating) { false } - let(:show_rejected) { false } - let(:show_withdrawn) { false } - let(:show_not_answered) { false } - - it "does not show any proposal" do - sleep(3) - expect(page.body).not_to have_selector("div[title='#{accepted_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{evaluating_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{rejected_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{withdrawn_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{null_state_proposal.title["en"]}']") - end - end - - context "when only the not answered option is enabled" do - let(:show_accepted) { false } - let(:show_evaluating) { false } - let(:show_rejected) { false } - let(:show_withdrawn) { false } - let(:show_not_answered) { true } - - it "only shows proposal without state" do - sleep(3) - expect(page.body).not_to have_selector("div[title='#{accepted_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{evaluating_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{rejected_proposal.title["en"]}']") - expect(page.body).not_to have_selector("div[title='#{withdrawn_proposal.title["en"]}']") - expect(page.body).to have_selector("div[title='#{null_state_proposal.title["en"]}']") - end - end - - # TODO: figure out a way to test leaflet without any map provider - # it "shows the proposal component as a menu" do - # expect(page.body).to have_content(".awesome_map-component_#{component.id}") - # end - - # it "shows amendments as a menu" do - # expect(page.body).to have_content(".awesome_map-amendments_#{component.id}") - # end - - # context "when hiding admendments" do - # let(:show_amendments) { false } - - # it "do not show the admendments menu item" do - # end - # end - - # context "when hiding meetings" do - # let(:show_meetings) { true } - - # it "do not show the meetings menu item" do - # end - # end -end diff --git a/spec/system/create_proposal_custom_fields_spec.rb b/spec/system/create_proposal_custom_fields_spec.rb deleted file mode 100644 index ed0fef6..0000000 --- a/spec/system/create_proposal_custom_fields_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Custom proposals fields", type: :system do - include_context "with a component" - let(:manifest_name) { "proposals" } - let!(:component) do - create(:proposal_component, - :with_creation_enabled, - manifest: manifest, - participatory_space: participatory_process) - end - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_bar } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - let(:slug) { participatory_process.slug } - - let(:data) { "[#{data1},#{data2},#{data3}]" } - let(:data1) { '{"type":"text","label":"Full Name","subtype":"text","className":"form-control","name":"text-1476748004559"}' } - let(:data2) { '{"type":"select","label":"Occupation","className":"form-control","name":"select-1476748006618","values":[{"label":"Street Sweeper","value":"option-1","selected":true},{"label":"Moth Man","value":"option-2"},{"label":"Chemist","value":"option-3"}]}' } - let(:data3) { '{"type":"textarea","label":"Short Bio","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - let(:custom_fields) do - { - "foo" => "[#{data1},#{data2}]", - "bar" => "[#{data3}]" - } - end - - before do - login_as user, scope: :user - visit_component - - click_link "New proposal" - end - - it "displays custom fields" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).to have_content("Short Bio") - expect(page).not_to have_css(".form-error.is-visible") - end - - context "when there are not custom fields" do - let(:custom_fields) do - { - "bar" => "[#{data3}]" - } - end - let(:slug) { "another-slug" } - - it "displays normal proposal editor" do - expect(page).to have_content("Title") - expect(page).to have_content("Body") - expect(page).not_to have_content("Full Name") - expect(page).not_to have_content("Occupation") - expect(page).not_to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - end - end - - context "and some are scoped to other places" do - let(:slug) { "another-slug" } - - it "displays the scoped fields" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).not_to have_content("Short Bio") - expect(page).not_to have_css(".form-error.is-visible") - end - end - - context "when creating the proposal" do - it "saves the proposal in XML" do - fill_in :proposal_title, with: "A far west character" - fill_in :"text-1476748004559", with: "Lucky Luke" - fill_in :"textarea-1476748007461", with: "I shot everything" - - click_button "Continue" - sleep 1 - expect(page).to have_content("Full Name") - expect(page).to have_xpath("//input[@class='form-control'][@id='text-1476748004559'][@user-data='Lucky Luke']") - expect(page).to have_content("Occupation") - expect(page).to have_content("Street Sweeper") - expect(page).to have_content("Short Bio") - expect(page).to have_xpath("//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot everything']") - expect(page).not_to have_css(".form-error.is-visible") - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
Lucky Luke
') - expect(Decidim::Proposals::Proposal.last.body["en"]).to include('
I shot everything
') - end - end -end diff --git a/spec/system/custom_redirects_spec.rb b/spec/system/custom_redirects_spec.rb deleted file mode 100644 index 6775c6e..0000000 --- a/spec/system/custom_redirects_spec.rb +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Custom Redirections", type: :system do - let(:organization) { create :organization } - let(:origin) { "/send-me-somewhere" } - let(:destination) { "/canary-islands" } - let(:active) { true } - let(:pass_query) { true } - let!(:config) { create :awesome_config, organization: organization, var: :custom_redirects, value: redirections } - let(:redirections) do - { - origin => { destination: destination, active: active, pass_query: pass_query }, - "/a-cheaper-place" => { destination: "/lloret", active: true, pass_query: false } - } - end - - before do - # ErrorController is only called when in production mode - unless ENV["SHOW_EXCEPTIONS"] - allow(Rails.application).to \ - receive(:env_config).with(no_args).and_wrap_original do |m, *| - m.call.merge( - "action_dispatch.show_exceptions" => true, - "action_dispatch.show_detailed_exceptions" => false - ) - end - end - - switch_to_host(organization.host) - end - - context "when no redirections" do - let(:redirections) { nil } - - it_behaves_like "a 404 page" do - let(:target_path) { origin } - end - end - - context "when redirection not configured" do - it_behaves_like "a 404 page" do - let(:target_path) { "/catch-me-if-you-can" } - end - end - - context "when redirection exists" do - it "redirects to destination" do - visit origin - - expect(page).to have_current_path(destination) - end - - context "when inactive" do - let(:active) { false } - - it_behaves_like "a 404 page" do - let(:target_path) { origin } - end - end - - context "when query string active" do - let(:query) { "passengers=2&dogs=1" } - let(:goto) { "#{origin}?#{query}" } - - it "passes query string to destination" do - visit goto - - expect(page).to have_current_path("#{destination}?#{query}") - expect(page).not_to have_current_path(destination) - end - - context "when destination has already a query string" do - let(:destination) { "/canary-islands?island=la-palma" } - - it "appends query string to destination" do - visit goto - - expect(page).to have_current_path("#{destination}&#{query}") - end - - context "when query string inactive" do - let(:pass_query) { false } - - it "do not pass the query string" do - visit goto - - expect(page).to have_current_path(destination) - end - end - end - end - - context "when origin is malformed" do - let(:goto) { "#{origin} " } - - it "reaches destination anyway" do - visit goto - - expect(page).to have_current_path(destination) - end - end - end -end diff --git a/spec/system/custom_styles_spec.rb b/spec/system/custom_styles_spec.rb deleted file mode 100644 index a06b497..0000000 --- a/spec/system/custom_styles_spec.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Custom styles", type: :system do - let(:organization) { create :organization } - let!(:participatory_process) { create :participatory_process, organization: organization } - let!(:config) { create :awesome_config, organization: organization, var: :scoped_styles, value: styles } - let(:config_helper) { create :awesome_config, organization: organization, var: :scoped_style_bar } - let(:styles) do - { - "bar" => "body {background: red;}" - } - end - - before do - switch_to_host(organization.host) - visit decidim.root_path - end - - shared_examples "extra css is added" do - it "css is present" do - expect(page.body).to have_content("body {background: red;}") - end - - it "css is applied" do - expect(page.execute_script("return window.getComputedStyle($('body')[0]).backgroundColor")).to eq("rgb(255, 0, 0)") - end - end - - shared_examples "no extra css is added" do - it "css is no present" do - expect(page.body).not_to have_content("body {background: red;}") - end - - it "css is not applyied" do - expect(page.execute_script("return window.getComputedStyle($('body')[0]).backgroundColor")).to eq("rgb(250, 250, 250)") - end - end - - context "when there are custom styles" do - it_behaves_like "extra css is added" - end - - context "when there are empty css boxes" do - let(:styles) do - {} - end - - it_behaves_like "no extra css is added" - end - - context "when constraints are present" do - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: settings) } - let!(:other_constraint) { create(:config_constraint, awesome_config: config_helper, settings: other_settings) } - let(:settings) do - {} - end - - let(:other_settings) do - { "participatory_space_manifest" => "other" } - end - - before do - visit decidim.root_path - end - - context "when there are custom styles" do - it_behaves_like "extra css is added" - end - - context "and there are no custom styles" do - let(:styles) do - {} - end - - it_behaves_like "no extra css is added" - end - - context "and custom styles are scoped" do - let(:settings) do - { "participatory_space_manifest" => "participatory_processes" } - end - - context "and page do not match the scope" do - it_behaves_like "no extra css is added" - end - - context "and page matches the scope" do - before do - click_link "Processes" - end - - it_behaves_like "extra css is added" - - context "and none constraint is present" do - let(:other_settings) do - { "participatory_space_manifest" => "none" } - end - - it_behaves_like "no extra css is added" - end - end - end - end - - context "when there are custom styles with special characters" do - let(:css) { %(body > a[href="hey"] { color: blue; }) } - let(:styles) do - { - "special" => css - } - end - - it "decodes them correctly" do - expect(page.body).to have_content(css) - end - end -end diff --git a/spec/system/edit_proposal_custom_fields_spec.rb b/spec/system/edit_proposal_custom_fields_spec.rb deleted file mode 100644 index 814ecf5..0000000 --- a/spec/system/edit_proposal_custom_fields_spec.rb +++ /dev/null @@ -1,225 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Custom proposals fields", type: :system do - include_context "with a component" - let(:manifest_name) { "proposals" } - let(:component) do - create(:proposal_component, - :with_creation_enabled, - :with_amendments_enabled, - manifest: manifest, - participatory_space: participatory_process) - end - let(:rte_enabled) { false } - let!(:proposal) { create :proposal, :with_amendments, users: [author], body: body, component: component } - let(:author) { create :user, :confirmed, organization: organization } - let!(:config) { create :awesome_config, organization: organization, var: :proposal_custom_fields, value: custom_fields } - let(:config_helper) { create :awesome_config, organization: organization, var: :proposal_custom_field_foo } - let!(:constraint) { create(:config_constraint, awesome_config: config_helper, settings: { "participatory_space_manifest" => "participatory_processes", "participatory_space_slug" => slug }) } - let(:slug) { participatory_process.slug } - let(:body) do - { en: answer } - end - let(:answer) { '
Occupation
Moth Man
Bio
I shot the sheriff
' } - let(:data) { "[#{data1},#{data2},#{data3}]" } - let(:data1) { '{"type":"text","label":"Full Name","subtype":"text","className":"form-control","name":"text-1476748004559"}' } - let(:data2) { '{"type":"select","label":"Occupation","className":"form-control","name":"select-1476748006618","values":[{"label":"Street Sweeper","value":"option-1","selected":true},{"label":"Moth Man","value":"option-2"},{"label":"Chemist","value":"option-3"}]}' } - let(:data3) { '{"type":"textarea","label":"Short Bio","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - let(:custom_fields) do - { - "foo" => "[#{data1},#{data2},#{data3}]" - } - end - - before do - organization.update(rich_text_editor_in_public_views: rte_enabled) - login_as user, scope: :user - visit_component - end - - shared_examples "has custom fields" do |textarea| - it "displays custom fields" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Moth Man") - expect(page).to have_xpath("//select[@class='form-control'][@id='select-1476748006618'][@user-data='option-2']") - expect(page).to have_content("Short Bio") - expect(page).to have_xpath(textarea) - expect(page).not_to have_css(".form-error.is-visible") - end - end - - shared_examples "saves custom fields" do |title_field, button, xpath| - it "saves the proposal in XML" do - fill_in title_field, with: "A far west character" - fill_in :"text-1476748004559", with: "Lucky Luke" - fill_in :"textarea-1476748007461", with: "I shot everything" - - click_button button - sleep 1 - expect(page).to have_content("Full Name") - if xpath - expect(page).to have_xpath("//input[@class='form-control'][@id='text-1476748004559'][@user-data='Lucky Luke']") - expect(page).to have_xpath("//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot everything']") - else - expect(page).to have_selector("dd#text-1476748004559", text: "Lucky Luke") - expect(page).to have_selector("dd#textarea-1476748007461", text: "I shot everything") - end - expect(page).to have_content("Occupation") - expect(page).to have_content("Moth Man") - expect(page).to have_content("Short Bio") - expect(page).not_to have_css(".form-error.is-visible") - end - end - - shared_examples "has default fields" do - it "displays title and body" do - expect(page).to have_content("Title") - expect(page).to have_content("Body") - expect(page).not_to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Moth Man") - expect(page).not_to have_content("Short Bio") - expect(page).to have_content("I shot the sheriff") - expect(page).not_to have_css(".form-error.is-visible") - end - end - - context "when editing the proposal" do - let(:author) { user } - - before do - click_link proposal.title["en"] - click_link "Edit proposal" - end - - it_behaves_like "has custom fields", "//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']" - it_behaves_like "saves custom fields", :proposal_title, "Send", false - - context "and has i18n keys" do - let(:data3) { '{"type":"textarea","label":"activemodel.attributes.user.nickname","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - it "displays the translation" do - expect(page).to have_content("Nickname") - expect(page).not_to have_content("activemodel.attributes.user.nickname") - expect(page).not_to have_content("Short Bio") - end - end - - context "and RTE is enabled" do - let(:rte_enabled) { true } - - it_behaves_like "has custom fields", "//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']" - it_behaves_like "saves custom fields", :proposal_title, "Send", false - end - - context "and custom fields are out of scope" do - let(:slug) { "another-slug" } - - it_behaves_like "has default fields" - end - - context "and proposal has unformatted content" do - let(:answer) { "I shot the Sheriff\\nbut not Deputy" } - - it "has custom fields with content in the first textarea" do - expect(page).to have_content("Title") - expect(page).not_to have_content("Body") - expect(page).to have_content("Full Name") - expect(page).to have_content("Occupation") - expect(page).to have_content("Moth Man") - expect(page).not_to have_xpath("//select[@class='form-control'][@id='select-1476748006618'][@user-data='option-2']") - expect(page).to have_content("Short Bio") - expect(page).to have_xpath("//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the Sheriff\\nbut not Deputy']") - expect(page).to have_css(".form-error.is-visible") - end - end - - context "and there a RicheText Editor type field" do - let(:data3) { '{"type":"textarea","subtype":"richtext","label":"Short Bio","rows":"5","className":"form-control","name":"textarea-1476748007461"}' } - - it "has custom fields with richttext editor" do - expect(page).to have_content("Full Name") - expect(page).to have_xpath("//input[@id='textarea-1476748007461-input'][contains(@value, 'I shot the sheriff')]", visible: :hidden) - expect(page).to have_content("Occupation") - expect(page).to have_content("Moth Man") - expect(page).to have_content("Short Bio") - expect(page).not_to have_css(".form-error.is-visible") - end - end - end - - context "when amending the proposal" do - before do - click_link proposal.title["en"] - click_link "Amend Proposal" - end - - it "is amendment editor page" do - expect(page).to have_content("CREATE AMENDMENT DRAFT") - end - - it_behaves_like "has custom fields", "//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']" - it_behaves_like "saves custom fields", :amendment_emendation_params_title, "Create", true - - context "and RTE is enabled" do - let(:rte_enabled) { true } - - it_behaves_like "has custom fields", "//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']" - it_behaves_like "saves custom fields", :amendment_emendation_params_title, "Create", true - end - - context "and custom fields are out of scope" do - let(:slug) { "another-slug" } - - it_behaves_like "has default fields" - end - end - - context "when participatory texts" do - let!(:participatory_text) { create :participatory_text, component: component } - let(:component) do - create(:proposal_component, - :with_creation_enabled, - :with_amendments_and_participatory_texts_enabled, - manifest: manifest, - participatory_space: participatory_process) - end - - before do - click_link proposal.title["en"] - click_link "Amend Proposal" - end - - it "is amendment editor page" do - expect(page).to have_content("CREATE AMENDMENT DRAFT") - end - - it_behaves_like "has default fields" - end - - context "when editing collaborative drafts" do - let(:component) do - create(:proposal_component, - :with_creation_enabled, - :with_collaborative_drafts_enabled, - manifest: manifest, - participatory_space: participatory_process) - end - let!(:collaborative_draft) { create :collaborative_draft, users: [author, user], body: answer, component: component } - - before do - click_link "Access collaborative drafts" - click_link collaborative_draft.title - click_link "Edit collaborative draft" - end - - it_behaves_like "has custom fields", "//textarea[@class='form-control'][@id='textarea-1476748007461'][@user-data='I shot the sheriff']" - it_behaves_like "saves custom fields", :collaborative_draft_title, "Send", false - end -end diff --git a/spec/system/edit_proposals_spec.rb b/spec/system/edit_proposals_spec.rb deleted file mode 100644 index 1216a6a..0000000 --- a/spec/system/edit_proposals_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/editor_examples" - -describe "Show proposals editor", type: :system do - include_context "with a component" - let(:manifest_name) { "proposals" } - let!(:component) do - create(:proposal_component, - manifest: manifest, - participatory_space: participatory_process) - end - - let!(:proposal) { create(:proposal, users: [user], component: component) } - let(:proposal_title) { translated(proposal.title) } - - let!(:user) { create :user, :confirmed, organization: organization } - let(:rte_enabled) { false } - let!(:allow_images_in_proposals) { create(:awesome_config, organization: organization, var: :allow_images_in_proposals, value: images_in_proposals) } - let!(:allow_images_in_small_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_small_editor, value: images_editor) } - let!(:use_markdown_editor) { create(:awesome_config, organization: organization, var: :use_markdown_editor, value: markdown_enabled) } - let!(:allow_images_in_markdown_editor) { create(:awesome_config, organization: organization, var: :allow_images_in_markdown_editor, value: markdown_images) } - let(:images_in_proposals) { false } - let(:images_editor) { false } - let(:markdown_enabled) { false } - let(:markdown_images) { false } - let(:editor_selector) { "#proposal_body" } - - before do - organization.update(rich_text_editor_in_public_views: rte_enabled) - login_as user, scope: :user - visit_component - - click_link proposal_title - click_link "Edit proposal" - end - - context "when rich text editor is enabled for participants" do - let(:rte_enabled) { true } - - it_behaves_like "has no drag and drop", true - - context "and images in RTE are enabled" do - let(:images_editor) { true } - - it_behaves_like "has drag and drop", true - end - - context "and markdown is enabled" do - let(:markdown_enabled) { true } - - it_behaves_like "has markdown editor" - - context "and images are enabled" do - let(:markdown_images) { true } - - it_behaves_like "has markdown editor", true - end - end - end - - context "when rich text editor is NOT enabled for participants" do - it_behaves_like "has no drag and drop" - - context "and images in proposals is enabled" do - let(:images_in_proposals) { true } - - it_behaves_like "has drag and drop" - end - - context "and markdown is enabled" do - let(:markdown_enabled) { true } - - it_behaves_like "has no markdown editor" - end - end - - context "when editing in markdown mode" do - let(:rte_enabled) { true } - let(:markdown_enabled) { true } - let(:text) { "# title\\n\\nParagraph\\nline 2" } - let(:html) { "

title

Paragraph
line 2

" } - - it "converts markdown to html before saving" do - sleep 1 - page.execute_script("$('[name=\"faker-inscrybmde\"]:first')[0].InscrybMDE.value('#{text}')") - - click_button "Send" - - expect(page).not_to have_content("# title") - expect(page).to have_selector("h1", text: "title") - expect(page).to have_selector("p", text: "Paragraph\nline 2") - expect(Decidim::Proposals::Proposal.last.body["en"].gsub(/[\n\r]/, "")).to eq(html) - end - end -end diff --git a/spec/system/homepage_spec.rb b/spec/system/homepage_spec.rb deleted file mode 100644 index 0160895..0000000 --- a/spec/system/homepage_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" - -describe "Visit the home page", type: :system, perform_enqueued: true do - let(:organization) { create :organization, available_locales: [:en] } - - before do - switch_to_host(organization.host) - visit decidim.root_path - end - - it "renders the home page" do - expect(page).to have_content("Home") - end - - it_behaves_like "javascript config vars" -end diff --git a/spec/system/menu_hacks_spec.rb b/spec/system/menu_hacks_spec.rb deleted file mode 100644 index f8be9df..0000000 --- a/spec/system/menu_hacks_spec.rb +++ /dev/null @@ -1,315 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Hacked menus", type: :system do - let(:organization) { create :organization } - let!(:participatory_process) { create :participatory_process, organization: organization } - let!(:config) { create :awesome_config, organization: organization, var: :menu, value: menu } - let(:menu) { [overriden, added] } - let(:overriden) do - { - url: "/", - label: { - "en" => "A new beggining" - }, - position: 10 - } - end - let(:added) do - { - url: "http://external.blog", - label: { - "en" => "Blog" - }, - position: 9 - } - end - let(:disabled_features) { [] } - - before do - disabled_features.each do |feature| - allow(Decidim::DecidimAwesome.config).to receive(feature).and_return(:disabled) - end - - switch_to_host(organization.host) - visit decidim.root_path - end - - shared_examples "has active link" do |text| - it "has only one active link" do - within ".main-nav" do - expect(page).to have_css(".main-nav__link--active", count: 1) - end - end - - it "active link containts text" do - within ".main-nav .main-nav__link--active" do - expect(page).to have_content(text) - end - end - end - - it "renders the hacked menu" do - within ".main-nav" do - expect(page).not_to have_content("Home") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - expect(page).to have_content("A new beggining") - expect(page).to have_content("Blog") - end - end - - it "renders in the proper order" do - within ".main-nav li:nth-child(1)" do - expect(page).to have_content("Processes") - end - within ".main-nav li:nth-child(2)" do - expect(page).to have_content("Help") - end - within ".main-nav li:nth-child(3)" do - expect(page).to have_content("Blog") - end - within ".main-nav li:last-child" do - expect(page).to have_content("A new beggining") - end - end - - context "when opens in a new window" do - let(:added) do - { - url: "http://external.blog", - label: { - "en" => "Blog" - }, - position: 9, - target: "_blank" - } - end - - it "has target blank" do - expect(find(".main-nav li:nth-child(3) a")[:class]).to include("external-link-container") - expect(find(".main-nav li:nth-child(3) a")[:target]).to eq("_blank") - expect(find(".main-nav li:last-child a")[:class]).not_to include("external-link-container") - end - end - - describe "visibility" do - let(:visibility) { "default" } - let(:overriden) do - { - url: "/", - label: { - "en" => "A new beggining" - }, - position: 10, - visibility: visibility - } - end - - it "renders the item" do - within ".main-nav" do - expect(page).to have_content("A new beggining") - end - end - - context "when hidden" do - let(:visibility) { "hidden" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when logged" do - let(:visibility) { "logged" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when non logged" do - let(:visibility) { "non_logged" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).to have_content("A new beggining") - end - end - end - - context "when user is logged" do - let!(:user) { create(:user, :confirmed, organization: organization) } - - before do - switch_to_host(organization.host) - login_as user, scope: :user - visit decidim.root_path - end - - context "when hidden" do - let(:visibility) { "hidden" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when logged" do - let(:visibility) { "logged" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).to have_content("A new beggining") - end - end - end - - context "when non logged" do - let(:visibility) { "non_logged" } - - it "do not show the menu item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when only verified user", with_authorization_workflows: ["dummy_authorization_handler"] do - let!(:authorization) { create(:authorization, granted_at: Time.zone.now, user: user, name: "dummy_authorization_handler") } - let(:visibility) { "verified_user" } - - before do - switch_to_host(organization.host) - login_as user, scope: :user - visit decidim.root_path - end - - context "when user is verified" do - it "shows the item" do - within ".main-nav" do - expect(page).to have_content("A new beggining") - end - end - end - - context "when user is not verified" do - let(:authorization) { nil } - - it "shows the item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - - context "when verification is expired" do - let!(:authorization) { create(:authorization, granted_at: 3.months.ago, user: user, name: "dummy_authorization_handler") } - - it "shows the item" do - within ".main-nav" do - expect(page).not_to have_content("A new beggining") - end - end - end - end - - describe "active" do - let!(:component) { create(:proposal_component, participatory_space: participatory_process) } - let!(:participatory_process2) { create :participatory_process, organization: organization } - let!(:component2) { create(:proposal_component, participatory_space: participatory_process2) } - let(:menu) do - [ - { - url: "/", - label: { - "en" => "A new beggining" - }, - position: 1 - }, - { - url: "/processes/#{participatory_process.slug}", - label: { - "en" => "A single process" - }, - position: 2 - } - ] - end - - it_behaves_like "has active link", "A new beggining" - - context "when visiting all processes list" do - before do - visit decidim_participatory_processes.participatory_processes_path - end - - it_behaves_like "has active link", "Processes" - end - - context "when visiting a process in a custom link" do - before do - visit decidim_participatory_processes.participatory_process_path(participatory_process.slug) - end - - it_behaves_like "has active link", "A single process" - end - - context "when visiting a sublink of a process in a custom link" do - before do - visit main_component_path(component) - end - - it_behaves_like "has active link", "A single process" - end - - context "when visiting a process not in a custom link" do - before do - visit decidim_participatory_processes.participatory_process_path(participatory_process2.slug) - end - - it_behaves_like "has active link", "Processes" - end - - context "when visiting a sublink of a process not in a custom link" do - before do - visit main_component_path(component2) - end - - it_behaves_like "has active link", "Processes" - end - end - - context "when menu is :disabled" do - let(:disabled_features) { [:menu] } - - it "renders the normal menu" do - within ".main-nav" do - expect(page).to have_content("Home") - expect(page).to have_content("Processes") - expect(page).to have_content("Help") - expect(page).not_to have_content("A new beggining") - expect(page).not_to have_content("Blog") - end - end - - it_behaves_like "has active link", "Home" - - context "when visiting another page" do - before do - visit decidim_participatory_processes.participatory_processes_path - end - - it_behaves_like "has active link", "Processes" - end - end - end - end -end diff --git a/spec/system/questionnaires_spec.rb b/spec/system/questionnaires_spec.rb deleted file mode 100644 index d957548..0000000 --- a/spec/system/questionnaires_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/decidim_awesome/test/shared_examples/config_examples" - -describe "Questionnaires", type: :system do - include_context "with a component" - let(:manifest_name) { "meetings" } - - let(:user) do - create :user, - :confirmed, - organization: organization - end - - let(:meeting) { create :meeting, :published, :online, :live, component: component } - let(:meeting_live_event_path) do - decidim_participatory_process_meetings.meeting_live_event_path( - participatory_process_slug: participatory_process.slug, - component_id: component.id, - meeting_id: meeting.id - ) - end - - it "does not have current_questionnaire" do - login_as user, scope: :user - visit meeting_live_event_path - expect(page.body).not_to have_content("window.DecidimAwesome.current_questionnaire") - end - - context "when questionnaire exist" do - let!(:poll) { create(:poll, meeting: meeting) } - let!(:questionnaire) { create(:meetings_poll_questionnaire, questionnaire_for: poll) } - let!(:question_single_option) { create(:meetings_poll_question, :unpublished, questionnaire: questionnaire) } - - it "has current_questionnaire" do - login_as user, scope: :user - visit meeting_live_event_path - expect(page.body).to have_content("window.DecidimAwesome.current_questionnaire") - end - end -end diff --git a/spec/system/voting_cards_spec.rb b/spec/system/voting_cards_spec.rb deleted file mode 100644 index c862d5b..0000000 --- a/spec/system/voting_cards_spec.rb +++ /dev/null @@ -1,573 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe "Voting weights with cards", type: :system do - include_context "with a component" - let(:voting_manifest) { :voting_cards } - let!(:component) { create :proposal_component, :with_votes_enabled, participatory_space: participatory_space, settings: settings } - let(:settings) do - { - vote_limit: vote_limit, - threshold_per_proposal: threshold_per_proposal, - can_accumulate_supports_beyond_threshold: can_accumulate_supports_beyond_threshold, - minimum_votes_per_user: minimum_votes_per_user, - awesome_voting_manifest: voting_manifest, - voting_cards_show_abstain: abstain, - voting_cards_box_title: { en: box_title }, - voting_cards_instructions: { en: instructions }, - voting_cards_show_modal_help: modal_help - } - end - let!(:proposals) { create_list(:proposal, 4, component: component) } - let(:proposal) { proposals.first } - let(:proposal_title) { translated(proposal.title) } - let(:user) { create :user, :confirmed, organization: organization } - let(:abstain) { true } - let(:box_title) { nil } - let(:instructions) { nil } - let(:modal_help) { true } - let!(:vote_weights) { nil } - let(:vote_limit) { 0 } - let(:threshold_per_proposal) { 0 } - let(:can_accumulate_supports_beyond_threshold) { false } - let(:minimum_votes_per_user) { 0 } - - context "when the user is logged in" do - before do - login_as user, scope: :user - visit_component - within "#proposal-#{proposal.id}-vote-button" do - click_link "Click to vote" - end - end - - it "has correct copies" do - expect(page).to have_content("Vote on this proposal") - expect(page).to have_content("ABSTAIN") - expect(page).to have_content("Green") - expect(page).to have_content("Red") - expect(page).to have_content("Yellow") - expect(page).not_to have_content("Change my vote") - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - - click_link "Abstain" - within ".vote_proposal_modal" do - expect(page).to have_content("My vote on \"#{strip_tags(proposal_title)}\" is \"Abstain\"") - expect(page).to have_content("Please read the election rules carefully to understand how your vote will be used by #{organization.name}") - click_button "Cancel" - end - %w(Green Yellow Red).each do |color| - within ".button--vote-button" do - click_link color - end - within ".vote_proposal_modal" do - expect(page).to have_content("My vote on \"#{strip_tags(proposal_title)}\" is \"#{color}\"") - click_button "Cancel" - end - end - end - - shared_examples "can vote" do |color, weight| - it "votes with modal" do - expect(page).to have_selector(".vote-count[data-weight=\"#{weight}\"]", text: "0") if weight != "0" - within ".button--vote-button" do - click_link color - end - within ".vote_proposal_modal" do - click_button "Proceed" - end - %w(0 1 2 3).each do |w| - expect(page).to have_selector(".vote-action.weight_#{w}.disabled") - if w == weight - expect(page).to have_selector(".vote-count[data-weight=\"#{w}\"]", text: "1") if w != "0" - expect(page).not_to have_selector(".vote-action.weight_#{w}.dim") - expect(page).to have_selector(".vote-action.weight_#{w}.voted") - else - expect(page).to have_selector(".vote-count[data-weight=\"#{w}\"]", text: "0") if w != "0" - expect(page).to have_selector(".vote-action.weight_#{w}.dim") - end - end - expect(page).to have_content("Change my vote") - end - end - - it_behaves_like "can vote", "Green", "3" - it_behaves_like "can vote", "Yellow", "2" - it_behaves_like "can vote", "Red", "1" - it_behaves_like "can vote", "Abstain", "0" - - context "when no abstain" do - let(:abstain) { false } - - it "has correct copies" do - expect(page).not_to have_content("ABSTAIN") - expect(page).to have_content("Green") - expect(page).to have_content("Red") - expect(page).to have_content("Yellow") - expect(page).not_to have_content("Change my vote") - end - end - - context "when no default title" do - let(:box_title) { "-" } - - it "has no title" do - expect(page).not_to have_content("Vote on this proposal") - end - end - - context "when custom title" do - let(:box_title) { "Custom title" } - - it "has custom title" do - expect(page).to have_content("Custom title") - end - end - - context "when custom modal message" do - let(:instructions) { "Custom instructions" } - - it "has custom modal message" do - click_link "Red" - within ".vote_proposal_modal" do - expect(page).to have_content("Custom instructions") - end - end - end - - context "when the proposal has votes" do - let(:modal_help) { false } - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3) - ] - end - - it "shows existing votes" do - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "3") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "2") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "1") - end - - it "updates vote counts when the user votes" do - click_link "Green" - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "2") - click_link "Change my vote" - click_link "Abstain" - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "1") - end - end - end - - context "when listing proposals" do - before do - login_as user, scope: :user - visit_component - end - - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0) - ] - end - - it "shows the vote count" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - expect(page).to have_content("Y: 2") - expect(page).to have_content("R: 3") - expect(page).to have_content("A: 4") - expect(page).to have_link("Click to vote") - end - end - - context "when votes are blocked" do - let!(:component) { create :proposal_component, :with_votes_blocked, participatory_space: participatory_space, settings: settings } - - it "shows the vote count and the vote button is disabled" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - expect(page).to have_content("SUPPORTS DISABLED") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "3") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "2") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "1") - expect(page).to have_selector(".vote-action.weight_1.disabled") - expect(page).to have_selector(".vote-action.weight_2.disabled") - expect(page).to have_selector(".vote-action.weight_3.disabled") - expect(page).to have_selector(".vote-action.weight_0.disabled") - expect(page).not_to have_content("Change my vote") - end - end - - context "when votes are hidden" do - let(:modal_help) { false } - - before do - component.update!(step_settings: { component.participatory_space.active_step.id => { votes_hidden: true, votes_enabled: true } }) - end - - it "shows the vote count and the vote button is disabled" do - visit_component - within "#proposal_#{proposal.id}" do - expect(page).not_to have_content("G: 1") - click_link "Click to vote" - end - expect(page).not_to have_selector(".vote-count[data-weight=\"1\"]") - expect(page).not_to have_selector(".vote-count[data-weight=\"2\"]") - expect(page).not_to have_selector(".vote-count[data-weight=\"3\"]") - expect(page).not_to have_content("Change my vote") - click_link "Green" - expect(page).not_to have_selector(".vote-count[data-weight=\"3\"]") - click_link "Change my vote" - click_link "Abstain" - expect(page).not_to have_selector(".vote-count[data-weight=\"3\"]") - end - end - - context "when vote limit has been reached" do - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[1], author: user), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[2], author: user), weight: 3) - ] - end - let(:vote_limit) { 3 } - - it "shows the vote count and the vote button is disabled" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 1") - expect(page).to have_content("A: 0") - expect(page).to have_content("VOTED") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - expect(page).to have_selector(".vote-action.weight_1.disabled") - expect(page).to have_selector(".vote-action.weight_2.disabled") - expect(page).to have_selector(".vote-action.weight_3.disabled") - expect(page).to have_selector(".vote-action.weight_0.disabled") - expect(page).to have_content("Change my vote") - end - - context "and has not voted on the proposal" do - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[1], author: user), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[2], author: user), weight: 3) - ] - end - let(:vote_limit) { 2 } - - it "shows the vote count and the vote button is disabled" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 1") - expect(page).to have_content("A: 0") - expect(page).to have_content("NO SUPPORTS REMAINING") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - expect(page).to have_selector(".vote-action.weight_1.disabled") - expect(page).to have_selector(".vote-action.weight_2.disabled") - expect(page).to have_selector(".vote-action.weight_3.disabled") - expect(page).to have_selector(".vote-action.weight_0.disabled") - expect(page).not_to have_content("Change my vote") - expect(page).to have_content("No supports remaining") - end - end - end - - context "when proposals have a voting limit" do - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1) - ] - end - let(:threshold_per_proposal) { 1 } - let(:modal_help) { false } - - it "shows the vote count and the vote button is disabled" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 1") - expect(page).to have_content("A: 0") - expect(page).to have_content("SUPPORT LIMIT REACHED") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - expect(page).to have_selector(".vote-action.weight_1.disabled") - expect(page).to have_selector(".vote-action.weight_2.disabled") - expect(page).to have_selector(".vote-action.weight_3.disabled") - expect(page).to have_selector(".vote-action.weight_0.disabled") - expect(page).to have_content("Support limit reached") - end - - context "and can accumulate more votes" do - let(:can_accumulate_supports_beyond_threshold) { true } - - it "shows the vote count and can vote" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 1") - expect(page).to have_content("A: 0") - expect(page).to have_content("CLICK TO VOTE") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "0") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - expect(page).not_to have_content("Change my vote") - click_link "Green" - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "1") - click_link "Change my vote" - click_link "Abstain" - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - end - end - end - - context "when proposals have a minimum amount of votes" do - let(:modal_help) { false } - let(:minimum_votes_per_user) { 2 } - let(:proposal2) { proposals[1] } - let!(:vote_weights) { [] } - - it "doesn't count votes unless the minimum is achieved" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - click_link "Green" - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "0") - visit_component - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 0") - end - within "#proposal_#{proposal2.id}" do - expect(page).to have_content("G: 0") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "0") - click_link "Red" - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - visit_component - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - click_link "Click to vote" - end - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "1") - visit_component - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - end - within "#proposal_#{proposal2.id}" do - expect(page).to have_content("R: 1") - end - end - end - - context "when proposal is rejected" do - let(:proposal) { create(:proposal, :rejected, component: component) } - let!(:vote_weights) { [] } - - it "shows the vote count" do - filter = legacy_version? ? ".state_check_boxes_tree_filter" : ".with_any_state_check_boxes_tree_filter" - within ".filters #{filter}" do - check "All" - uncheck "All" - check "Rejected" - end - within "#proposal_#{proposal.id}" do - expect(page).not_to have_content("G: 0") - expect(page).not_to have_content("Y: 0") - expect(page).not_to have_content("R: 0") - expect(page).not_to have_content("A: 0") - expect(page).to have_content("REJECTED") - expect(page).not_to have_content("Click to vote") - end - end - end - - context "when abstain is disabled" do - let(:abstain) { false } - - it "shows the vote count" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - expect(page).to have_content("Y: 2") - expect(page).to have_content("R: 3") - expect(page).not_to have_content("A: 4") - expect(page).to have_link("Click to vote") - end - end - end - - context "when the user has voted" do - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[1], author: user), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[2], author: user), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposals[3], author: user), weight: 0) - ] - end - - it "shows the vote count" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 3") - expect(page).to have_content("Y: 2") - expect(page).to have_content("R: 1") - expect(page).to have_content("A: 0") - expect(page).to have_link("Voted") - expect(page).to have_css("a.button.weight_1") - end - within "#proposal_#{proposals[1].id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 1") - expect(page).to have_content("R: 0") - expect(page).to have_content("A: 0") - expect(page).to have_link("Voted") - expect(page).to have_css("a.button.weight_2") - end - within "#proposal_#{proposals[2].id}" do - expect(page).to have_content("G: 1") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 0") - expect(page).to have_content("A: 0") - expect(page).to have_link("Voted") - expect(page).to have_css("a.button.weight_3") - end - within "#proposal_#{proposals[3].id}" do - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 0") - expect(page).to have_content("R: 0") - expect(page).to have_content("A: 1") - expect(page).to have_link("Voted") - expect(page).to have_css("a.button.weight_0") - end - end - - context "when votes are blocked" do - let!(:component) { create :proposal_component, :with_votes_blocked, participatory_space: participatory_space, settings: settings } - - it "shows the vote count and the vote button is disabled" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 3") - click_link "Voted" - end - expect(page).to have_selector(".vote-count[data-weight=\"1\"]", text: "1") - expect(page).to have_selector(".vote-count[data-weight=\"2\"]", text: "2") - expect(page).to have_selector(".vote-count[data-weight=\"3\"]", text: "3") - expect(page).to have_selector(".vote-action.weight_1.disabled") - expect(page).to have_selector(".vote-action.weight_2.disabled") - expect(page).to have_selector(".vote-action.weight_3.disabled") - expect(page).not_to have_content("Change my vote") - end - end - end - end - - context "when the user is not logged in" do - before do - visit_component - end - - let!(:vote_weights) do - [ - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 1), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 2), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 3), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0), - create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal), weight: 0) - ] - end - - it "shows the vote count", :caching do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("G: 1") - expect(page).to have_content("Y: 2") - expect(page).to have_content("R: 3") - expect(page).to have_content("A: 4") - expect(page).to have_link("Click to vote") - # check the cached card by maintaining the number of votes and change the weight - Decidim::DecidimAwesome::VoteWeight.find_by(weight: 3).update(weight: 1) - visit_component - expect(page).to have_content("G: 0") - expect(page).to have_content("Y: 2") - expect(page).to have_content("R: 4") - end - end - - context "when no voting_manifest" do - let(:voting_manifest) { nil } - - it "has normal support button" do - within "#proposal_#{proposal.id}" do - expect(page).to have_content("Support") - expect(page).not_to have_content("G:") - expect(page).not_to have_content("Y:") - expect(page).not_to have_content("R:") - click_link proposal.title["en"] - end - - within ".button--vote-button" do - expect(page).to have_content("Support") - expect(page).not_to have_content("Green") - expect(page).not_to have_content("Yellow") - expect(page).not_to have_content("Red") - end - end - end - - it "show the modal window on voting" do - within "#proposal_#{proposal.id}" do - click_link "Click to vote" - end - expect(page).to have_selector("#loginModal", visible: :hidden) - click_link "Abstain" - expect(page).to have_selector("#loginModal", visible: :visible) - end - end -end diff --git a/spec/types/proposal_type_spec.rb b/spec/types/proposal_type_spec.rb deleted file mode 100644 index e89bde5..0000000 --- a/spec/types/proposal_type_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "decidim/api/test/type_context" - -module Decidim::Proposals - describe ProposalType, type: :graphql do - include_context "with a graphql class type" - let(:component) { create(:proposal_component) } - let!(:extra_fields) { create(:awesome_proposal_extra_fields, :with_votes, proposal: model) } - let(:model) { create :proposal, component: component } - - describe "id" do - let(:query) { "{ id }" } - - it "returns the proposal's id" do - expect(response["id"]).to eq(model.id.to_s) - end - end - - describe "voteCount/voteWeights" do - let(:query) { "{ voteCount voteWeights }" } - - context "when votes are not hidden" do - it "returns the amount of votes for this proposal" do - expect(response["voteCount"]).to eq(5) - end - - it "returns the weights of votes for this proposal" do - expect(response["voteWeights"]).to eq({ "1" => 1, "2" => 1, "3" => 1, "4" => 1, "5" => 1 }) - end - end - - context "when votes are hidden" do - let(:component) { create(:proposal_component, :with_votes_hidden) } - - it "returns nil" do - expect(response["voteCount"]).to be_nil - expect(response["voteWeights"]).to be_nil - end - end - end - end -end diff --git a/spec/uploaders/cw/image_uploader_spec.rb b/spec/uploaders/cw/image_uploader_spec.rb deleted file mode 100644 index e47c10d..0000000 --- a/spec/uploaders/cw/image_uploader_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" -require "carrierwave/test/matchers" - -module Decidim::Cw::DecidimAwesome - describe ImageUploader do - include CarrierWave::Test::Matchers - - let(:organization) { build(:organization) } - let(:user) { build(:user, organization: organization) } - let(:image) { Decidim::Dev.test_file("city.jpeg", "image/jpeg") } - let(:uploader) { ImageUploader.new(user, :image) } - - before do - ImageUploader.enable_processing = true - File.open(image) { |f| uploader.store!(f) } - end - - after do - ImageUploader.enable_processing = false - uploader.remove! - end - - it "compress the image" do - expect(uploader.file.size).to be < File.size(image) - end - - it "makes the image readable only to the owner and not executable" do - expect(uploader).to have_permissions(0o666) - end - - it "has the correct format" do - expect(uploader).to be_format("jpeg") - end - end -end