@@ -74,6 +74,24 @@ def create_role(group:, type: Group::Mitglieder::Aktivmitglied, person: Fabricat
7474 end
7575 end
7676
77+ describe "#total_count" do
78+ it "counts active roles at to_date, across the whole hierarchy" do
79+ create_role ( group : mitglieder , start_on : Date . new ( 2024 , 3 , 1 ) )
80+ create_role ( group : kontakte , type : Group ::Kontakte ::Kontakt , start_on : Date . new ( 2024 , 7 , 1 ) )
81+
82+ # 2 additional roles plus berner_mitglied and no_permissions fixtures
83+ expect ( statistic ( range ) . total_count ) . to eq ( 4 )
84+ end
85+
86+ it "does not count roles from a different layer" do
87+ zuercher = groups ( :zuercher_mitglieder )
88+ create_role ( group : zuercher , start_on : Date . new ( 2024 , 3 , 1 ) )
89+
90+ # only berner_mitglied and no_permissions fixtures are in the layer
91+ expect ( statistic ( range ) . total_count ) . to eq ( 2 )
92+ end
93+ end
94+
7795 describe "a role type change within the same group" do
7896 it "counts as both an exit for the old type and an entry for the new type" do
7997 person = Fabricate ( :person )
@@ -90,42 +108,44 @@ def create_role(group:, type: Group::Mitglieder::Aktivmitglied, person: Fabricat
90108 end
91109
92110 describe "#group_breakdowns" do
93- it "lists every descendant group in the layer, even ones without any changes" do
111+ it "lists only groups with entries, exits or count in the layer" do
112+ create_role ( group : mitglieder , start_on : Date . new ( 2024 , 3 , 1 ) )
94113 titles = statistic ( range ) . group_breakdowns . map ( &:title )
95- expect ( titles ) . to contain_exactly ( "Gremium" , "Vorstand" , "Geschäftsstelle" , " Mitglieder",
96- "Kontakte" )
114+ expect ( titles ) . to include ( " Mitglieder")
115+ expect ( titles ) . to include ( "Kontakte" )
97116 end
98117
99- it "gives a group without changes an empty role_rows and a zeroed total_row" do
100- breakdown = statistic ( range ) . group_breakdowns . find { |b | b . title == "Kontakte" }
101- expect ( breakdown . role_rows ) . to be_empty
102- expect ( breakdown . total_row . to_h ) . to eq ( entries : 0 , exits : 0 , net : 0 )
103- end
104-
105- it "returns entries/exits/net per role type, plus a summed total_row" do
118+ it "returns entries/exits/net/count per role type, plus a summed total_row" do
119+ # role(:berner_mitglied) from fixtures is also counted
106120 create_role ( group : mitglieder , type : Group ::Mitglieder ::Aktivmitglied ,
107121 start_on : Date . new ( 2024 , 3 , 1 ) )
108122 create_role ( group : mitglieder , type : Group ::Mitglieder ::Freimitglied ,
109123 start_on : Date . new ( 2020 , 1 , 1 ) , end_on : Date . new ( 2024 , 6 , 1 ) )
110124
111125 breakdown = statistic ( range ) . group_breakdowns . find { |b | b . title == "Mitglieder" }
112126 expect ( breakdown . role_rows . map ( &:to_h ) ) . to contain_exactly (
113- { label : "Aktivmitglied" , entries : 1 , exits : 0 , net : 1 } ,
114- { label : "Freimitglied" , entries : 0 , exits : 1 , net : -1 }
127+ { label : "Aktivmitglied" , entries : 1 , exits : 0 , net : 1 , count : 2 } ,
128+ { label : "Freimitglied" , entries : 0 , exits : 1 , net : -1 , count : 0 }
115129 )
116- expect ( breakdown . total_row . to_h ) . to eq ( entries : 1 , exits : 1 , net : 0 )
130+ expect ( breakdown . total_row . to_h ) . to eq ( entries : 1 , exits : 1 , net : 0 , count : 2 )
117131 end
118132
119- it "builds a breadcrumb title for a nested group, excluding the layer itself" do
120- Fabricate ( Group ::Mitglieder . sti_name . to_sym , parent : mitglieder , name : "Aktive" )
133+ it "builds a breadcrumb title for a nested group, excluding the layer name itself" do
134+ aktive = Fabricate ( Group ::Mitglieder . sti_name . to_sym , parent : mitglieder , name : "Aktive" )
135+ create_role ( group : aktive , start_on : Date . new ( 2024 , 3 , 1 ) )
121136
122137 titles = statistic ( range ) . group_breakdowns . map ( &:title )
123138 expect ( titles ) . to include ( "Mitglieder → Aktive" )
124139 end
125140
126- it "does not include the layer itself in the breakdown" do
127- titles = statistic ( range ) . group_breakdowns . map ( &:title )
128- expect ( titles ) . not_to include ( layer . to_s )
141+ it "includes the layer itself in the breakdown with suffix when it has entries/exits" do
142+ root = groups ( :schweizer_wanderwege )
143+ create_role ( group : root , type : Group ::SchweizerWanderwege ::Mitarbeitende ,
144+ start_on : Date . new ( 2024 , 3 , 1 ) )
145+ stat = described_class . new ( root , ActionController ::Parameters . new ( range ) )
146+
147+ titles = stat . group_breakdowns . map ( &:title )
148+ expect ( titles ) . to include ( "#{ root } (nur Hauptgruppe ohne Untergruppen)" )
129149 end
130150 end
131151
@@ -152,7 +172,9 @@ def create_role(group:, type: Group::Mitglieder::Aktivmitglied, person: Fabricat
152172 create_role ( group : aktive , start_on : Date . new ( 2024 , 3 , 1 ) )
153173 create_role ( group : kontakte , type : Group ::Kontakte ::Kontakt , start_on : Date . new ( 2024 , 3 , 1 ) )
154174 stat = described_class . new ( mitglieder . reload , ActionController ::Parameters . new ( range ) )
155- expect ( stat . group_breakdowns . map ( &:title ) ) . to contain_exactly ( "Mitglieder → Aktive" )
175+ expect ( stat . group_breakdowns . map ( &:title ) ) . to contain_exactly (
176+ "Mitglieder (nur Hauptgruppe ohne Untergruppen)" , "Mitglieder → Aktive"
177+ )
156178 expect ( stat . total_entries ) . to eq ( 1 )
157179 end
158180 end
0 commit comments