diff --git a/app/jobs/decidim/civicrm/rebuild_verifications_job.rb b/app/jobs/decidim/civicrm/rebuild_verifications_job.rb index 83f6258..b834298 100644 --- a/app/jobs/decidim/civicrm/rebuild_verifications_job.rb +++ b/app/jobs/decidim/civicrm/rebuild_verifications_job.rb @@ -15,6 +15,7 @@ def perform(workflow_name, organization_id) User.where(organization: organization_id).find_each do |user| next unless user.civicrm_identity? + user.contact&.rebuild! perform_auth(user) end end diff --git a/app/models/decidim/civicrm/contact.rb b/app/models/decidim/civicrm/contact.rb index 0127f74..e3f933c 100644 --- a/app/models/decidim/civicrm/contact.rb +++ b/app/models/decidim/civicrm/contact.rb @@ -20,6 +20,20 @@ def possible_memberships decidim_civicrm_groups: { decidim_organization_id: decidim_organization_id } }) end + + def memberships + @memberships ||= MembershipType.where(civicrm_membership_type_id: membership_types) + end + + # re-fetch info from the api + def rebuild! + result = Decidim::Civicrm::Api::FindContact.new(civicrm_contact_id).result + return if result.blank? + + self.membership_types = result[:memberships] + self.extra = result[:contact] + save! + end end end end diff --git a/app/views/decidim/civicrm/admin/membership_types/index.html.erb b/app/views/decidim/civicrm/admin/membership_types/index.html.erb index e61907d..5c76498 100644 --- a/app/views/decidim/civicrm/admin/membership_types/index.html.erb +++ b/app/views/decidim/civicrm/admin/membership_types/index.html.erb @@ -20,7 +20,7 @@ <% membership_types.each do |membership_type| %> - <%= membership_type.id %> + <%= membership_type.civicrm_membership_type_id %> <%= membership_type.name %> <%= l(membership_type.created_at, format: :decidim_short) if membership_type.created_at %> diff --git a/lib/decidim/civicrm/api/find_contact.rb b/lib/decidim/civicrm/api/find_contact.rb index 576883d..84686cc 100644 --- a/lib/decidim/civicrm/api/find_contact.rb +++ b/lib/decidim/civicrm/api/find_contact.rb @@ -24,6 +24,8 @@ def default_query end def self.parse_item(item) + return {} unless item.is_a?(Hash) + contact = { id: item["id"].to_i, display_name: item["display_name"] diff --git a/spec/jobs/rebuild_verifications_job_spec.rb b/spec/jobs/rebuild_verifications_job_spec.rb index 9059336..4215638 100644 --- a/spec/jobs/rebuild_verifications_job_spec.rb +++ b/spec/jobs/rebuild_verifications_job_spec.rb @@ -11,15 +11,16 @@ module Decidim::Civicrm let(:data) { JSON.parse(file_fixture("find_user_valid_response.json").read) } let(:user) { create :user, organization: organization } - let!(:identity) { create :identity, user: user, provider: Decidim::Civicrm::OMNIAUTH_PROVIDER_NAME } + let!(:identity) { create :identity, user: user, provider: Decidim::Civicrm::OMNIAUTH_PROVIDER_NAME, uid: uid } let(:organization) { create :organization } let!(:group) { create :civicrm_group, organization: organization } - let!(:membership_type) { create :civicrm_membership_type, organization: user.organization, civicrm_membership_type_id: type_id } - let!(:contact) { create :civicrm_contact, user: user, organization: organization, civicrm_contact_id: contact_id, membership_types: types } - let(:types) { [type_id] } - let(:type_id) { data["values"].first["api.Membership.get"]["values"].first["id"] } + let!(:membership_type1) { create :civicrm_membership_type, organization: user.organization, civicrm_membership_type_id: 1 } + let!(:membership_type2) { create :civicrm_membership_type, organization: user.organization, civicrm_membership_type_id: 2 } + let!(:membership_type3) { create :civicrm_membership_type, organization: user.organization, civicrm_membership_type_id: 3 } + let!(:contact) { create :civicrm_contact, user: user, organization: organization, civicrm_contact_id: contact_id, membership_types: [2, 3] } let!(:membership) { create :civicrm_group_membership, group: group, contact: contact, civicrm_contact_id: contact_id } - let(:contact_id) { data["id"] } + let(:uid) { data["id"] } + let(:contact_id) { "9999" } shared_examples "destroys and rebuilds verification" do it "creates the verification" do @@ -72,6 +73,30 @@ module Decidim::Civicrm it_behaves_like "destroys and rebuilds verification" do let(:klass) { Decidim::Civicrm::Verifications::CivicrmMembershipTypes } let(:workflow_name) { :civicrm_membership_types } + + it "has metadata" do + subject.perform_now(workflow_name, organization.id) + expect(Decidim::Authorization.find_by(user: user, name: workflow_name).metadata).to eq({ "contact_id" => 9999, "membership_types_ids" => [2, 3], "uid" => 42 }) + end + end + + context "when contact has been updated" do + let(:workflow_name) { :civicrm_membership_types } + let(:contact_data) do + { contact: { id: 42, display_name: "Lady Trillian" }, memberships: [1] } + end + + before do + # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(Decidim::Civicrm::Api::FindContact).to receive(:result).and_return(contact_data) + # rubocop:enable RSpec/AnyInstance + end + + it "creates the verification with the new data" do + subject.perform_now(workflow_name, organization.id) + expect(Decidim::Authorization.where(user: user, name: workflow_name).count).to eq(1) + expect(Decidim::Authorization.find_by(user: user, name: workflow_name).metadata).to eq({ "contact_id" => 9999, "membership_types_ids" => [1], "uid" => 42 }) + end end context "when the workflow_name is not a civicrm authorization" do diff --git a/spec/models/civicrm/contact_spec.rb b/spec/models/civicrm/contact_spec.rb index b7dd1cf..df01d7f 100644 --- a/spec/models/civicrm/contact_spec.rb +++ b/spec/models/civicrm/contact_spec.rb @@ -7,7 +7,7 @@ module Decidim::Civicrm subject { described_class.new(organization: organization, user: user, civicrm_contact_id: 1) } let!(:organization) { create(:organization) } - let!(:user) { create(:user) } + let!(:user) { create(:user, organization: organization) } it { is_expected.to be_valid } @@ -39,4 +39,19 @@ module Decidim::Civicrm end end end + + context "when rebuilding the contact" do + include_context "with stubs example api" + + let(:data) { JSON.parse(file_fixture("find_contact_valid_response.json").read) } + let(:organization) { create(:organization) } + let(:user) { create(:user, organization: organization) } + let!(:contact) { create :civicrm_contact, user: user, organization: organization, civicrm_contact_id: data["id"], membership_types: [1] } + + it "rebuilds the contact" do + expect(contact.extra["display_name"]).not_to eq("Sir Arthur Dent") + expect { contact.rebuild! }.to change(contact, :membership_types).to([2, 3]) + expect(contact.extra["display_name"]).to eq("Sir Arthur Dent") + end + end end diff --git a/spec/system/admin_spec.rb b/spec/system/admin_spec.rb index 89127ec..e6edf87 100644 --- a/spec/system/admin_spec.rb +++ b/spec/system/admin_spec.rb @@ -9,7 +9,13 @@ let!(:user) { create :user, :admin, :confirmed, organization: organization } let!(:groups) { create_list :civicrm_group, 3, organization: organization } - let!(:membership_types) { create_list :civicrm_membership_type, 3, organization: organization } + let!(:membership_types) do + [ + create(:civicrm_membership_type, organization: organization, civicrm_membership_type_id: 123), + create(:civicrm_membership_type, organization: organization, civicrm_membership_type_id: 456), + create(:civicrm_membership_type, organization: organization, civicrm_membership_type_id: 789) + ] + end let!(:contact) { create :civicrm_contact, organization: organization } let!(:group_membership) { create :civicrm_group_membership, contact: contact, group: groups.first } @@ -121,6 +127,9 @@ expect(page).to have_link("Synchronize with CiViCRM") within ".civicrm-membership-types" do + expect(page).to have_content(membership_types[0].civicrm_membership_type_id) + expect(page).to have_content(membership_types[1].civicrm_membership_type_id) + expect(page).to have_content(membership_types[2].civicrm_membership_type_id) expect(page).to have_content(membership_types[0].name) expect(page).to have_content(membership_types[1].name) expect(page).to have_content(membership_types[2].name)