import os from application_harness import Application for resource in ['EMAIL','TICKET','REPLY','EXPORT']:os.environ['HCR_CLUB_'+resource+'_HOURLY']='2' app=Application();checks=0 def check(ok,message): global checks if not ok:raise AssertionError(message) checks+=1;print('PASS:',message) def tickets():return app.fixture('inspect')['club_tickets'] try: ids=app.fixture('tenantSeed');a=ids['clubA'];b=ids['clubB'] app.login('membera@example.test','Tenant test password 123!') check(app.post('Roster.tickets',step='openTicket',club_serial=a,subject='First',message='Body')[0]==200,'First member can submit within the shared ticket budget');tid=tickets()[0]['ticket_serial'] app.logout();app.login('shared@example.test','Tenant test password 123!') check(app.post('Roster.tickets',step='openTicket',club_serial=a,subject='Second',message='Body')[0]==200,'Another member shares the same ticket budget') check(app.post('Roster.tickets',step='openTicket',club_serial=a,subject='Limited',message='Body')[0]==429 and len(tickets())==2,'Club ticket limit rejects further work without partial records') app.logout();app.login('admina2@example.test','Tenant test password 123!') for n in range(2):check(app.post('Roster.tickets',step='reply',club_serial=a,ticket_serial=tid,message='Reply '+str(n))[0]==200,'Club reply budget permits an authorized reply') check(app.post('Roster.tickets',step='reply',club_serial=a,ticket_serial=tid,message='Limited')[0]==429,'Club reply limit is enforced through HTTP') check(app.post('Roster.workspace',step='invite',club_serial=a,invite_email='one@example.test')[0]==200,'Invitation email uses the shared club budget') check(app.post('RosterReports.csv',club_serial=a)[0]==200,'Roster export uses the shared export budget') app.logout();app.login('admina@example.test','Tenant test password 123!') check(app.post('Roster.workspace',step='invite',club_serial=a,invite_email='two@example.test')[0]==200,'Another administrator shares the email budget') check(app.post('Roster.workspace',step='invite',club_serial=a,invite_email='three@example.test')[0]==429,'Club email limit rejects additional invitations') check(app.post('RosterReports.ledger',club_serial=a)[0]==200,'Different export formats share one club budget') check(app.post('RosterReports.excel',club_serial=a)[0]==429,'Export budget applies across administrators and formats') check(app.post('RosterReports.csv',club_serial=b)[0]==403,'An ordinary member cannot consume a foreign export budget') app.logout();app.login('adminb@example.test','Tenant test password 123!') check(app.post('RosterReports.csv',club_serial=b)[0]==200,'Other club exports remain available after the first club reaches its limit') check(app.post('Roster.workspace',step='invite',club_serial=b,invite_email='beta@example.test')[0]==200,'Other club email remains available after the first club reaches its limit') print(checks,'resource HTTP checks passed.') finally:app.close()