Skip to content

Commit

Permalink
Center on account form (#14)
Browse files Browse the repository at this point in the history
* Center on account form

* Fix CI and reorder overrides in engine.rb

* Account spec

* Registration spec

* Disable cov on monkey-patched unhappy paths
  • Loading branch information
fblupi authored Dec 1, 2023
1 parent cd871fc commit 662ce09
Show file tree
Hide file tree
Showing 18 changed files with 355 additions and 2 deletions.
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PATH
specs:
decidim-centers (0.1.0.dev)
decidim-core (>= 0.27.0, < 0.28)
deface (~> 1.9)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -329,6 +330,12 @@ GEM
declarative-builder (0.1.0)
declarative-option (< 0.2.0)
declarative-option (0.1.0)
deface (1.9.0)
actionview (>= 5.2)
nokogiri (>= 1.6)
polyglot
railties (>= 5.2)
rainbow (>= 2.1.0)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (4.9.3)
Expand Down Expand Up @@ -565,6 +572,7 @@ GEM
pg_search (2.3.6)
activerecord (>= 5.2)
activesupport (>= 5.2)
polyglot (0.3.5)
premailer (1.21.0)
addressable
css_parser (>= 1.12.0)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require "active_support/concern"

module Decidim
module Centers
module CreateOmniauthRegistrationOverride
extend ActiveSupport::Concern

include PublishCenterUpdateEvent

def call
verify_oauth_signature!

begin
if existing_identity
# :nocov:
user = existing_identity.user
verify_user_confirmed(user)

return broadcast(:ok, user)
# :nocov:
end
return broadcast(:invalid) if form.invalid?

transaction do
create_or_find_user
@identity = create_identity
end
trigger_omniauth_registration
publish_center_update_event

broadcast(:ok, @user)
rescue ActiveRecord::RecordInvalid => e
# :nocov:
broadcast(:error, e.record)
# :nocov:
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

require "active_support/concern"

module Decidim
module Centers
module CreateRegistrationOverride
extend ActiveSupport::Concern

include PublishCenterUpdateEvent

def call
if form.invalid?
# :nocov:
user = User.has_pending_invitations?(form.current_organization.id, form.email)
user.invite!(user.invited_by) if user
return broadcast(:invalid)
# :nocov:
end

create_user
publish_center_update_event

broadcast(:ok, @user)
rescue ActiveRecord::RecordInvalid
# :nocov:
broadcast(:invalid)
# :nocov:
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require "active_support/concern"

module Decidim
module Centers
module PublishCenterUpdateEvent
extend ActiveSupport::Concern

def publish_center_update_event
ActiveSupport::Notifications.publish(
"decidim.centers.user.updated",
user_id: @user.id,
center_id: @form.center_id
)
end
end
end
end
35 changes: 35 additions & 0 deletions app/commands/concerns/decidim/centers/update_account_override.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require "active_support/concern"

module Decidim
module Centers
module UpdateAccountOverride
extend ActiveSupport::Concern

include PublishCenterUpdateEvent

def call
return broadcast(:invalid) unless @form.valid?

update_personal_data
update_avatar
update_password

if @user.valid?
@user.save!
notify_followers
publish_center_update_event
broadcast(:ok, @user.unconfirmed_email.present?)
else
# :nocov:
[:avatar, :password, :password_confirmation].each do |key|
@form.errors.add key, @user.errors[key] if @user.errors.has_key? key
end
broadcast(:invalid)
# :nocov:
end
end
end
end
end
27 changes: 27 additions & 0 deletions app/forms/concerns/decidim/centers/account_form_override.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require "active_support/concern"

module Decidim
module Centers
module AccountFormOverride
extend ActiveSupport::Concern

included do
alias_method :original_map_model, :map_model

include Decidim::Centers::ApplicationHelper

attribute :center_id, Integer

validates :center_id, presence: true

def map_model(model)
original_map_model(model)

self.center_id = model.center.try(:id)
end
end
end
end
end
7 changes: 7 additions & 0 deletions app/helpers/decidim/centers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ module Centers
# Custom helpers, scoped to the centers engine.
#
module ApplicationHelper
include TranslatableAttributes

def center_options_for_select
Decidim::Centers::Center.where(organization: current_organization).map do |center|
[center.id, translated_attribute(center.title)]
end
end
end
end
end
29 changes: 29 additions & 0 deletions app/jobs/decidim/centers/sync_center_user_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Decidim
module Centers
class SyncCenterUserJob < ApplicationJob
queue_as :default

def perform(data)
@user = Decidim::User.find(data[:user_id])
@center = Decidim::Centers::Center.find(data[:center_id])
create_or_update_center_user
end

private

def create_or_update_center_user
Decidim::Centers::CreateOrUpdateCenterUser.call(@center, @user) do
on(:ok) do
Rails.logger.info "SyncCenterUserJob: Success: updated for user #{@user.id}"
end

on(:invalid) do
Rails.logger.error "SyncCenterUserJob: ERROR: not updated for user #{@user.id}"
end
end
end
end
end
end
3 changes: 3 additions & 0 deletions app/overrides/decidim/account/show/centers.html.erb.deface
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- insert_after "erb[loud]:contains('email_field')" original "d629550ba83d41a6d1c41553b7adbed311549633" -->

<%= render partial: "/decidim/centers/profile_form", locals: { f: f } %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- insert_after "erb[loud]:contains('email_field')" -->

<%= render partial: "/decidim/centers/registration_form", locals: { f: f } %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- insert_before "#card__tos" -->

<%= render partial: "/decidim/centers/registration_form", locals: { f: f } %>
1 change: 1 addition & 0 deletions app/views/decidim/centers/_profile_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= f.collection_select :center_id, f.object.center_options_for_select, :first, :last %>
7 changes: 7 additions & 0 deletions app/views/decidim/centers/_registration_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="card">
<div class="card__content card__centers">
<div class="field">
<%= f.collection_select :center_id, f.object.center_options_for_select, :first, :last %>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions decidim-centers.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ Gem::Specification.new do |s|
s.files = Dir["{app,config,lib}/**/*", "LICENSE-AGPLv3.txt", "Rakefile", "README.md"]

s.add_dependency "decidim-core", Decidim::Centers::COMPAT_DECIDIM_VERSION
s.add_dependency "deface", "~> 1.9"
end
18 changes: 17 additions & 1 deletion lib/decidim/centers/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "rails"
require "decidim/core"
require "deface"

module Decidim
module Centers
Expand All @@ -16,10 +17,25 @@ class Engine < ::Rails::Engine
end

config.to_prepare do
# commands
Decidim::CreateOmniauthRegistration.prepend(Decidim::Centers::CreateOmniauthRegistrationOverride)
Decidim::CreateRegistration.prepend(Decidim::Centers::CreateRegistrationOverride)
Decidim::UpdateAccount.prepend(Decidim::Centers::UpdateAccountOverride)
# forms
Decidim::RegistrationForm.include(Decidim::Centers::AccountFormOverride)
Decidim::OmniauthRegistrationForm.include(Decidim::Centers::AccountFormOverride)
Decidim::AccountForm.include(Decidim::Centers::AccountFormOverride)
# models
Decidim::User.include(Decidim::Centers::UserOverride)
end

initializer "Centers.webpacker.assets_path" do
initializer "decidim_centers.sync" do
ActiveSupport::Notifications.subscribe "decidim.centers.user.updated" do |_name, data|
Decidim::Centers::SyncCenterUserJob.perform_now(data)
end
end

initializer "decidim_centers.webpacker.assets_path" do
Decidim.register_assets_path File.expand_path("app/packs", root)
end
end
Expand Down
11 changes: 10 additions & 1 deletion spec/lib/overrides_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
{
package: "decidim-core",
files: {
"/app/models/decidim/user.rb" => "3d57a7c9130a91d44e1acd7475877b87"
"/app/commands/decidim/create_omniauth_registration.rb" => "586139f98ded0645eb83e480ef5dd6bd",
"/app/commands/decidim/create_registration.rb" => "8bf3456d42c21036d08ccafe16e9105a",
"/app/commands/decidim/update_account.rb" => "29d81617f5bf1af310d2777a916b4d8b",
"/app/forms/decidim/account_form.rb" => "73a8150ed1620d515a1c96f680e98ec0",
"/app/forms/decidim/omniauth_registration_form.rb" => "ee09e2b5675c9d1cb4dc955dded05393",
"/app/forms/decidim/registration_form.rb" => "32b55eb5a1742b6b8ed7bbb4c7643dc0",
"/app/models/decidim/user.rb" => "3d57a7c9130a91d44e1acd7475877b87",
"/app/views/decidim/account/show.html.erb" => "567f47fd001a0222943579d9ebfe5f3a",
"/app/views/decidim/devise/omniauth_registrations/new.html.erb" => "81d19863520eb70fd228deec786e739a",
"/app/views/decidim/devise/registrations/new.html.erb" => "5f6f15330839fa55697c4e272767a090"
}
}
]
Expand Down
59 changes: 59 additions & 0 deletions spec/system/account_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

require "spec_helper"

describe "Account", type: :system do
let(:organization) { create :organization }
let(:user) { create :user, :confirmed, organization: organization }
let!(:center) { create :center, organization: organization }
let!(:other_center) { create :center, organization: organization }

before do
switch_to_host(organization.host)
login_as user, scope: :user
end

shared_examples_for "user changes the center" do
it "can update the center" do
within "form.edit_user" do
within "#user_center_id" do
find("option[value='#{other_center.id}']").click
end

find("*[type=submit]").click
end

within_flash_messages do
expect(page).to have_content("successfully")
end

expect(find("#user_center_id").value).to eq(other_center.id.to_s)
end
end

context "when the user doesn't have center" do
before do
visit decidim.account_path
end

it "shows an empty value on the center input" do
expect(find("#user_center_id").value).to eq("")
end

include_examples "user changes the center"
end

context "when the user has center" do
let!(:center_user) { create :center_user, center: center, user: user }

before do
visit decidim.account_path
end

it "shows the current center on the center input" do
expect(find("#user_center_id").value).to eq(center.id.to_s)
end

include_examples "user changes the center"
end
end
Loading

0 comments on commit 662ce09

Please sign in to comment.