Skip to content

Commit 337c3f1

Browse files
authored
Merge pull request #2578 from mroderick/feature/add-eligible-methods-to-chapter
feat: display eligible member counts in admin pages
2 parents 537aac3 + 2a0fdf7 commit 337c3f1

6 files changed

Lines changed: 74 additions & 9 deletions

File tree

app/models/chapter.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ def coaches
4848
.distinct
4949
end
5050

51+
def eligible_students
52+
Member.in_group(groups.students).distinct
53+
end
54+
55+
def eligible_coaches
56+
Member.in_group(groups.coaches).distinct
57+
end
58+
5159
private
5260

5361
def expire_chapters_sidebar_cache

app/models/group.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ class Group < ApplicationRecord
2020
def to_s
2121
"#{name} #{chapter.name}"
2222
end
23+
24+
def eligible_members
25+
members.not_banned.accepted_toc.distinct
26+
end
2327
end

app/views/admin/chapters/show.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
- @groups.each do |group|
3131
%li.nav-item
3232
= link_to [ :admin, group ], class: 'nav-link' do
33-
#{group.name} (#{group.members.count})
33+
#{group.name} (#{group.eligible_members.count} eligible, #{group.members.count} total)
3434
%li.nav-item
3535
= link_to admin_chapter_members_path(@chapter, type: group.name.downcase), class: 'nav-link' do
3636
View #{group.name} emails

app/views/admin/groups/show.html.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
.row
99
.col
10-
%h3.mb-3 Members (#{@group.members.count})
10+
%h3.mb-3 Members (#{@group.eligible_members.count} eligible, #{@group.members.count} total)
1111
%table.table.table-striped.table-hover
1212
%tbody
1313
- @group.members.each do |member|

spec/models/chapter_spec.rb

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
RSpec.describe Chapter do
2-
it { should validate_presence_of(:city) }
3-
it { should validate_length_of(:description).is_at_most(280) }
2+
it { is_expected.to validate_presence_of(:city) }
3+
it { is_expected.to validate_length_of(:description).is_at_most(280) }
44

55
context 'validations' do
6-
context '#slug' do
6+
describe '#slug' do
77
it 'a chapter must have a slug set' do
88
chapter = Chapter.new(name: 'London', city: 'London', email: 'london@codebar.io')
99
chapter.save
@@ -19,7 +19,7 @@
1919
end
2020
end
2121

22-
context '#time_zone' do
22+
describe '#time_zone' do
2323
it 'requires a time zone' do
2424
chapter = Fabricate(:chapter)
2525
expect(chapter).to be_valid
@@ -32,7 +32,7 @@
3232
end
3333

3434
context 'scopes' do
35-
context '#active' do
35+
describe '#active' do
3636
it 'only returns active Chapters' do
3737
1.times { Fabricate(:chapter) }
3838
2.times { Fabricate(:chapter, active: false) }
@@ -65,4 +65,40 @@
6565
expect(Rails.cache.read(cache_key)).to be_nil
6666
end
6767
end
68+
69+
describe '#eligible_students' do
70+
let(:chapter) { Fabricate(:chapter) }
71+
let(:student_group) { Fabricate(:group, chapter: chapter, name: 'Students') }
72+
73+
it 'includes only students with accepted TOC who are not banned' do
74+
eligible_student = Fabricate(:member, groups: [student_group], accepted_toc_at: Time.zone.now)
75+
_ineligible_no_toc = Fabricate(:member, groups: [student_group], accepted_toc_at: nil)
76+
_ineligible_banned = Fabricate(:banned_member, groups: [student_group], accepted_toc_at: Time.zone.now)
77+
78+
expect(chapter.eligible_students).to contain_exactly(eligible_student)
79+
end
80+
81+
it 'returns empty relation when no eligible students' do
82+
Fabricate(:member, groups: [student_group], accepted_toc_at: nil)
83+
expect(chapter.eligible_students).to be_empty
84+
end
85+
end
86+
87+
describe '#eligible_coaches' do
88+
let(:chapter) { Fabricate(:chapter) }
89+
let(:coach_group) { Fabricate(:group, chapter: chapter, name: 'Coaches') }
90+
91+
it 'includes only coaches with accepted TOC who are not banned' do
92+
eligible_coach = Fabricate(:member, groups: [coach_group], accepted_toc_at: Time.zone.now)
93+
_ineligible_no_toc = Fabricate(:member, groups: [coach_group], accepted_toc_at: nil)
94+
_ineligible_banned = Fabricate(:banned_member, groups: [coach_group], accepted_toc_at: Time.zone.now)
95+
96+
expect(chapter.eligible_coaches).to contain_exactly(eligible_coach)
97+
end
98+
99+
it 'returns empty relation when no eligible coaches' do
100+
Fabricate(:member, groups: [coach_group], accepted_toc_at: nil)
101+
expect(chapter.eligible_coaches).to be_empty
102+
end
103+
end
68104
end

spec/models/group_spec.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,29 @@
22
subject(:group) { Fabricate.build(:group) }
33

44
context 'validations' do
5-
it { should validate_presence_of(:name) }
5+
it { is_expected.to validate_presence_of(:name) }
66

77
it do
8-
should validate_inclusion_of(:name)
8+
expect(subject).to validate_inclusion_of(:name)
99
.in_array(%w[Coaches Students])
1010
.with_message('Invalid name for Group')
1111
end
1212
end
13+
14+
describe '#eligible_members' do
15+
let(:group) { Fabricate(:group, name: 'Students') }
16+
17+
it 'includes only members with accepted TOC who are not banned' do
18+
eligible_member = Fabricate(:member, groups: [group], accepted_toc_at: Time.zone.now)
19+
_ineligible_no_toc = Fabricate(:member, groups: [group], accepted_toc_at: nil)
20+
_ineligible_banned = Fabricate(:banned_member, groups: [group], accepted_toc_at: Time.zone.now)
21+
22+
expect(group.eligible_members).to contain_exactly(eligible_member)
23+
end
24+
25+
it 'returns empty relation when no eligible members' do
26+
Fabricate(:member, groups: [group], accepted_toc_at: nil)
27+
expect(group.eligible_members).to be_empty
28+
end
29+
end
1330
end

0 commit comments

Comments
 (0)