22# This file is part of the Pycroft project and licensed under the terms of
33# the Apache License, Version 2.0. See the LICENSE file for details
44from datetime import datetime , date
5+ from typing import Sequence
56
67import pytest
78
89from pycroft .helpers .interval import closed , closedopen
9- from pycroft .lib .user_deletion import get_archivable_members , archive_users
10+ from pycroft .helpers .utc import with_min_time
11+ from pycroft .lib .user_deletion import (
12+ get_archivable_members ,
13+ archive_users ,
14+ ArchivableMemberInfo ,
15+ )
16+ from pycroft .model .user import User
1017from tests .factories import UserFactory , ConfigFactory , MembershipFactory , \
1118 PropertyGroupFactory , \
1219 HostFactory
@@ -26,27 +33,49 @@ def test_users_without_membership_not_in_list(session):
2633 assert get_archivable_members (session ) == []
2734
2835
29- def assert_archivable_members (members , expected_user , expected_end_date ):
30- match members :
31- case [(user , mem_id , mem_end )]:
32- assert user == expected_user
33- assert mem_id is not None
34- assert mem_end .date () == expected_end_date
35- case _:
36- pytest .fail ()
36+ def filter_members (members , user ):
37+ return [(u , id , end ) for u , id , end in members if u == user ]
3738
3839
39- class TestUserDeletion :
40+ def assert_member_present (
41+ members : Sequence [ArchivableMemberInfo ],
42+ expected_user : User ,
43+ expected_end_date : date ,
44+ ):
45+ relevant_members = filter_members (members , expected_user )
46+ assert len (relevant_members ) == 1
47+ [(_ , mem_id , mem_end )] = relevant_members
48+ assert mem_id is not None
49+ assert mem_end .date () == expected_end_date
50+
51+
52+ def assert_member_absent (
53+ members : Sequence [ArchivableMemberInfo ],
54+ expected_absent_user : User ,
55+ ):
56+ assert not filter_members (members , expected_absent_user )
57+
58+
59+ class TestArchivableUserSelection :
60+ @pytest .fixture (
61+ scope = "class" ,
62+ params = [date (2020 , 3 , 1 ), date (2020 , 1 , 1 ), date (2020 , 12 , 15 )],
63+ )
64+ def end_date (self , request ):
65+ return request .param
66+
4067 @pytest .fixture (scope = 'class' )
4168 def do_not_archive_group (self , class_session ):
4269 return PropertyGroupFactory (granted = {'do-not-archive' })
4370
44- @pytest .fixture (scope = ' class' )
45- def old_user (self , class_session , config , do_not_archive_group ) :
71+ @pytest .fixture (scope = " class" )
72+ def old_user (self , class_session , config , do_not_archive_group , end_date ) -> User :
4673 user = UserFactory .create (
4774 registered_at = datetime (2000 , 1 , 1 ),
4875 with_membership = True ,
49- membership__active_during = closed (datetime (2020 , 1 , 1 ), datetime (2020 , 3 , 1 )),
76+ membership__active_during = closed (
77+ with_min_time (date (2020 , 1 , 1 )), with_min_time (end_date )
78+ ),
5079 membership__group = config .member_group ,
5180 )
5281 MembershipFactory .create (
@@ -66,31 +95,38 @@ def do_not_archive_membership(self, session, old_user, do_not_archive_group):
6695 active_during = closedopen (datetime (2020 , 1 , 1 ), None ),
6796 )
6897
69- def test_old_users_in_deletion_list (self , session , old_user ):
70- members = get_archivable_members (session )
71- assert_archivable_members (members , old_user , date (2020 , 3 , 1 ))
98+ @pytest .mark .parametrize ("year" , [2022 , 2023 , 2024 ])
99+ def test_old_users_in_deletion_list_after (self , session , old_user , year , end_date ):
100+ members = get_archivable_members (session , current_year = year )
101+ assert_member_present (members , old_user , end_date )
72102
73- def test_old_user_not_in_list_with_long_delta (self , session , old_user ):
74- delta = date .today () - date (2020 , 1 , 1 ) # before 2020-03-01
75- assert get_archivable_members (session , delta ) == []
103+ @pytest .mark .parametrize ("year" , [2019 , 2020 , 2021 ])
104+ def test_old_user_not_in_list_before (self , session , old_user , year ):
105+ assert_member_absent (
106+ get_archivable_members (session , current_year = year ), old_user
107+ )
76108
77- def test_user_with_do_not_archive_not_in_list (self , session , old_user ,
78- do_not_archive_membership ):
79- assert get_archivable_members (session ) == []
109+ @pytest .mark .parametrize ("year" , list (range (2018 , 2023 )))
110+ def test_user_with_do_not_archive_not_in_list (
111+ self , session , old_user , do_not_archive_membership , year
112+ ):
113+ assert_member_absent (
114+ get_archivable_members (session , current_year = year ), old_user
115+ )
80116
81117 @pytest .mark .parametrize ('num_hosts' , [0 , 2 ])
82- def test_user_with_host_in_list (self , session , old_user , num_hosts ):
118+ def test_user_with_host_in_list (self , session , old_user , num_hosts , end_date ):
83119 if num_hosts :
84120 HostFactory .create_batch (num_hosts , owner = old_user )
85121 members = get_archivable_members (session )
86- assert_archivable_members (members , old_user , date ( 2020 , 3 , 1 ) )
122+ assert_member_present (members , old_user , end_date )
87123
88- def test_user_with_room_in_list (self , session , old_user ):
124+ def test_user_with_room_in_list (self , session , old_user , end_date ):
89125 with session .begin_nested ():
90126 old_user .room = None
91127 session .add (old_user )
92128 members = get_archivable_members (session )
93- assert_archivable_members (members , old_user , date ( 2020 , 3 , 1 ) )
129+ assert_member_present (members , old_user , end_date )
94130
95131
96132class TestUserArchival :
0 commit comments