diff --git a/CHANGELOG.md b/CHANGELOG.md index 85d2f888..5c1f00b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changed - Removed useless system tests and cover map functionality with Playwright e2e tests instead. +- Number of family members on self-hosted instances is no longer limited. # [0.34.2] - 2025-10-31 diff --git a/app/models/family.rb b/app/models/family.rb index 51123293..4764fc66 100644 --- a/app/models/family.rb +++ b/app/models/family.rb @@ -11,6 +11,8 @@ class Family < ApplicationRecord MAX_MEMBERS = 5 def can_add_members? + return true if DawarichSettings.self_hosted? + (member_count + pending_invitations_count) < MAX_MEMBERS end @@ -32,6 +34,8 @@ class Family < ApplicationRecord end def full? + return false if DawarichSettings.self_hosted? + (member_count + pending_invitations_count) >= MAX_MEMBERS end diff --git a/app/policies/family_invitation_policy.rb b/app/policies/family_invitation_policy.rb deleted file mode 100644 index 2369458b..00000000 --- a/app/policies/family_invitation_policy.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -class FamilyInvitationPolicy < ApplicationPolicy - def show? - # Public endpoint for invitation acceptance - no authentication required - true - end - - def create? - user.family == record.family && user.family_owner? - end - - def accept? - # Users can accept invitations sent to their email - user.email == record.email - end - - def destroy? - # Only family owners can cancel invitations - user.family == record.family && user.family_owner? - end -end diff --git a/app/policies/family_membership_policy.rb b/app/policies/family_membership_policy.rb deleted file mode 100644 index 1b50c18e..00000000 --- a/app/policies/family_membership_policy.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -class FamilyMembershipPolicy < ApplicationPolicy - def show? - user.family == record.family - end - - def update? - # Users can update their own settings - return true if user == record.user - - # Family owners can update any member's settings - user.family == record.family && user.family_owner? - end - - def destroy? - # Users can remove themselves (handled by family leave logic) - return true if user == record.user - - # Family owners can remove other members - user.family == record.family && user.family_owner? - end -end diff --git a/spec/models/family_spec.rb b/spec/models/family_spec.rb index 7f81b898..215372f6 100644 --- a/spec/models/family_spec.rb +++ b/spec/models/family_spec.rb @@ -26,31 +26,100 @@ RSpec.describe Family, type: :model do describe '#can_add_members?' do let(:family) { create(:family, creator: user) } - context 'when family has fewer than max members' do + context 'when not in self-hosted mode' do before do - create(:family_membership, family: family, user: user, role: :owner) - create_list(:family_membership, 3, family: family, role: :member) + allow(DawarichSettings).to receive(:self_hosted?).and_return(false) end - it 'returns true' do - expect(family.can_add_members?).to be true + context 'when family has fewer than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + end + + it 'returns true' do + expect(family.can_add_members?).to be true + end + end + + context 'when family has max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + end + + it 'returns false' do + expect(family.can_add_members?).to be false + end + end + + context 'when family has pending invitations that would reach max' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + create(:family_invitation, family: family, invited_by: user, status: :pending) + end + + it 'returns false' do + expect(family.can_add_members?).to be false + end + end + + context 'when family has no members' do + it 'returns true' do + expect(family.can_add_members?).to be true + end end end - context 'when family has max members' do + context 'when in self-hosted mode' do before do - create(:family_membership, family: family, user: user, role: :owner) - create_list(:family_membership, 4, family: family, role: :member) + allow(DawarichSettings).to receive(:self_hosted?).and_return(true) end - it 'returns false' do - expect(family.can_add_members?).to be false - end - end + context 'when family has fewer than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + end - context 'when family has no members' do - it 'returns true' do - expect(family.can_add_members?).to be true + it 'returns true' do + expect(family.can_add_members?).to be true + end + end + + context 'when family has max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + end + + it 'returns true (no limit in self-hosted mode)' do + expect(family.can_add_members?).to be true + end + end + + context 'when family has more than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 10, family: family, role: :member) + end + + it 'returns true (no limit in self-hosted mode)' do + expect(family.can_add_members?).to be true + end + end + + context 'when family has pending invitations that would exceed max' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + create_list(:family_invitation, 5, family: family, invited_by: user, status: :pending) + end + + it 'returns true (no limit in self-hosted mode)' do + expect(family.can_add_members?).to be true + end end end end @@ -122,4 +191,99 @@ RSpec.describe Family, type: :model do expect(Family::Membership.find_by(id: membership.id)).to be_nil end end + + describe '#full?' do + let(:family) { create(:family, creator: user) } + + context 'when not in self-hosted mode' do + before do + allow(DawarichSettings).to receive(:self_hosted?).and_return(false) + end + + context 'when family has fewer than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + end + + it 'returns false' do + expect(family.full?).to be false + end + end + + context 'when family has exactly max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + end + + it 'returns true' do + expect(family.full?).to be true + end + end + + context 'when family has pending invitations that would reach max' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + create(:family_invitation, family: family, invited_by: user, status: :pending) + end + + it 'returns true' do + expect(family.full?).to be true + end + end + end + + context 'when in self-hosted mode' do + before do + allow(DawarichSettings).to receive(:self_hosted?).and_return(true) + end + + context 'when family has fewer than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 3, family: family, role: :member) + end + + it 'returns false' do + expect(family.full?).to be false + end + end + + context 'when family has exactly max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + end + + it 'returns false (no limit in self-hosted mode)' do + expect(family.full?).to be false + end + end + + context 'when family has more than max members' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 10, family: family, role: :member) + end + + it 'returns false (no limit in self-hosted mode)' do + expect(family.full?).to be false + end + end + + context 'when family has pending invitations that would exceed max' do + before do + create(:family_membership, family: family, user: user, role: :owner) + create_list(:family_membership, 4, family: family, role: :member) + create_list(:family_invitation, 5, family: family, invited_by: user, status: :pending) + end + + it 'returns false (no limit in self-hosted mode)' do + expect(family.full?).to be false + end + end + end + end end diff --git a/spec/requests/users/registrations_spec.rb b/spec/requests/users/registrations_spec.rb index 6a5989ea..726c2ac3 100644 --- a/spec/requests/users/registrations_spec.rb +++ b/spec/requests/users/registrations_spec.rb @@ -51,8 +51,8 @@ RSpec.describe 'Users::Registrations', type: :request do get new_user_registration_path expect(response).to have_http_status(:ok) - expect(response.body).to include('Register now!') - expect(response.body).to include('take control over your location data') + expect(response.body).to include('Almost there!') + expect(response.body).to include('control over your location data') expect(response.body).not_to include('Join') expect(response.body).to include('Sign up') end @@ -227,7 +227,7 @@ RSpec.describe 'Users::Registrations', type: :request do get new_user_registration_path expect(response).to have_http_status(:ok) - expect(response.body).to include('Register now!') + expect(response.body).to include('Almost there!') end it 'allows account creation' do diff --git a/spec/services/families/accept_invitation_spec.rb b/spec/services/families/accept_invitation_spec.rb index 28dca538..cd515284 100644 --- a/spec/services/families/accept_invitation_spec.rb +++ b/spec/services/families/accept_invitation_spec.rb @@ -99,6 +99,7 @@ RSpec.describe Families::AcceptInvitation do context 'when family is at max capacity' do before do + allow(DawarichSettings).to receive(:self_hosted?).and_return(false) # Fill family to max capacity create_list(:family_membership, Family::MAX_MEMBERS, family: family, role: :member) end diff --git a/spec/services/families/invite_spec.rb b/spec/services/families/invite_spec.rb index 8ea3c747..087d3331 100644 --- a/spec/services/families/invite_spec.rb +++ b/spec/services/families/invite_spec.rb @@ -57,6 +57,7 @@ RSpec.describe Families::Invite do context 'when family is at max capacity' do before do + allow(DawarichSettings).to receive(:self_hosted?).and_return(false) # Create max members (5 total including owner) create_list(:family_membership, Family::MAX_MEMBERS - 1, family: family, role: :member) end