diff --git a/app/controllers/mailing_lists_controller.rb b/app/controllers/mailing_lists_controller.rb index 24032ba83..ddd0e3f59 100644 --- a/app/controllers/mailing_lists_controller.rb +++ b/app/controllers/mailing_lists_controller.rb @@ -4,6 +4,7 @@ class MailingListsController < ApplicationController before_action :require_access def create + MemberActivityRecorder.record(actor: current_user, key: 'mailing_list.subscribe') subscribe_to_newsletter(current_user) flash[:notice] = I18n.t('subscriptions.messages.mailing_list.subscribe') @@ -11,6 +12,7 @@ def create end def destroy + MemberActivityRecorder.record(actor: current_user, key: 'mailing_list.unsubscribe') unsubscribe_from_newsletter(current_user) flash[:notice] = I18n.t('subscriptions.messages.mailing_list.unsubscribe') diff --git a/app/controllers/member/details_controller.rb b/app/controllers/member/details_controller.rb index 6800f420e..f348d67af 100644 --- a/app/controllers/member/details_controller.rb +++ b/app/controllers/member/details_controller.rb @@ -24,6 +24,7 @@ def update return render :edit unless @member.update(attrs) @member.newsletter ? subscribe_to_newsletter(@member) : unsubscribe_from_newsletter(@member) + MemberActivityRecorder.record(actor: @member, key: 'profile.updated') redirect_to step2_member_path end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index fa659a3ea..79d52f2ac 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -24,6 +24,7 @@ def profile def update if @member.update(member_params) + MemberActivityRecorder.record(actor: current_user, key: 'profile.updated') notice = 'Your details have been updated.' redirect_to profile_path, notice: else diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 2c86fe90c..535a2ea59 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -7,11 +7,13 @@ def index @member = MemberPresenter.new(current_user) end - def create + def create # rubocop:disable Metrics/MethodLength subscription = Subscription.new(group_id:, member: current_user) if subscription.save SubscriptionMailingListService.subscribe(subscription) + MemberActivityRecorder.record(actor: current_user, key: 'subscription.created', + trackable: subscription.group) send_welcome_email(current_user, subscription) flash[:notice] = I18n.t('subscriptions.messages.group.subscribe', chapter: subscription.group.chapter.city, role: subscription.group.name) @@ -21,14 +23,18 @@ def create redirect_back fallback_location: root_path end - def destroy + def destroy # rubocop:disable Metrics/MethodLength # Don't error if subscription is not found subscription = current_user.subscriptions.find_by(group_id:) SubscriptionMailingListService.unsubscribe(subscription) if subscription subscription&.destroy - # Instead, rely on the group's existence (rather than the subscription) group = Group.find(group_id) + if subscription + MemberActivityRecorder.record(actor: current_user, key: 'subscription.removed', + trackable: group) + end + flash[:notice] = I18n.t('subscriptions.messages.group.unsubscribe', chapter: group.chapter.city, role: group.name) diff --git a/app/controllers/terms_and_conditions_controller.rb b/app/controllers/terms_and_conditions_controller.rb index a0d3be421..036966c28 100644 --- a/app/controllers/terms_and_conditions_controller.rb +++ b/app/controllers/terms_and_conditions_controller.rb @@ -22,6 +22,7 @@ def update member = current_user member.accepted_toc_at = Time.zone.now member.save(validate: false) + MemberActivityRecorder.record(actor: member, key: 'toc.accepted') redirect_to previous_path else flash[notice] = I18n.t('terms_and_conditions.messages.notice') diff --git a/spec/requests/member_activity_profile_spec.rb b/spec/requests/member_activity_profile_spec.rb new file mode 100644 index 000000000..76951385c --- /dev/null +++ b/spec/requests/member_activity_profile_spec.rb @@ -0,0 +1,35 @@ +# spec/requests/member_activity_profile_spec.rb +require 'rails_helper' + +RSpec.describe 'Profile activity' do + let(:member) { Fabricate(:member, email: 'profile@example.com') } + + before do + Fabricate(:auth_service, member:, provider: 'github', uid: 'profile-uid-1') + mock_auth_hash(provider: 'github', uid: 'profile-uid-1', email: member.email) + post '/auth/github/callback' # sign in via real OAuth callback + end + + it 'records profile.updated on MembersController#update' do + put member_path(member), params: { member: { about_you: 'updated bio' } } + + expect(PublicActivity::Activity.exists?(owner: member, key: 'profile.updated')).to be(true) + end + + it 'records profile.updated on Member::DetailsController#update' do + put member_details_path, params: { member: { about_you: 'details bio', how_you_found_us: 'social_media' } } + + expect(PublicActivity::Activity.exists?(owner: member, key: 'profile.updated')).to be(true) + end + + it 'records toc.accepted' do + # Seed session[:previous_request_url] via a GET to root_path — + # accept_terms before_action fires, calls store_path, then redirects + # to terms_and_conditions (which skips accept_terms) + get root_path + + put terms_and_conditions_path, params: { terms_and_conditions_form: { terms: '1' } } + + expect(PublicActivity::Activity.exists?(owner: member, key: 'toc.accepted')).to be(true) + end +end diff --git a/spec/requests/member_activity_subscriptions_spec.rb b/spec/requests/member_activity_subscriptions_spec.rb new file mode 100644 index 000000000..695c485f7 --- /dev/null +++ b/spec/requests/member_activity_subscriptions_spec.rb @@ -0,0 +1,31 @@ +# spec/requests/member_activity_subscriptions_spec.rb +require 'rails_helper' + +RSpec.describe 'Subscription and mailing list activity' do + let(:member) { Fabricate(:member) } + let(:group) { Fabricate(:group) } + + before do + Fabricate(:auth_service, member:, provider: 'github', uid: 'subs-uid-1') + mock_auth_hash(provider: 'github', uid: 'subs-uid-1', email: member.email) + post '/auth/github/callback' # sign in via real OAuth callback + end + + it 'records subscription.created and subscription.removed' do + post subscriptions_path, params: { subscription: { group_id: group.id } } + + expect(PublicActivity::Activity.exists?(owner: member, key: 'subscription.created')).to be(true) + + delete destroy_subscriptions_path, params: { subscription: { group_id: group.id } } + + expect(PublicActivity::Activity.exists?(owner: member, key: 'subscription.removed')).to be(true) + end + + it 'records mailing_list.subscribe and unsubscribe' do + post mailing_lists_path + expect(PublicActivity::Activity.exists?(owner: member, key: 'mailing_list.subscribe')).to be(true) + + delete mailing_lists_path + expect(PublicActivity::Activity.exists?(owner: member, key: 'mailing_list.unsubscribe')).to be(true) + end +end