Let users email personal reports on demand
This commit is contained in:
@@ -491,3 +491,71 @@ class RecapEmailTests(unittest.TestCase):
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
class OnDemandReportTests(RecapFixture, unittest.IsolatedAsyncioTestCase):
|
||||
async def test_new_confirmation_defaults_to_manual_without_changing_schedule(self):
|
||||
with patch.object(mail, 'send_email'):
|
||||
result = await recaps.subscribe(self.user)
|
||||
self.assertFalse(result['automatic_monthly'])
|
||||
self.assertFalse(store.settings()['enabled'])
|
||||
self.assertEqual(result['state'], 'pending')
|
||||
with self.assertRaises(recaps.RecapError):
|
||||
recaps.queue_personal(self.user, None, 'pending')
|
||||
|
||||
async def test_manual_current_month_delivers_with_monthly_schedule_off(self):
|
||||
sub, _ = self.subscribe()
|
||||
store.set_automatic(self.user['id'], False)
|
||||
month = datetime.now(timezone.utc).strftime('%Y-%m')
|
||||
queued = recaps.queue_personal(self.user, month, 'manual-1')
|
||||
self.assertEqual(recaps.queue_personal(self.user, month, 'manual-1')['id'], queued['id'])
|
||||
report = {**self.report, **month_periods(month, datetime.now(timezone.utc))}
|
||||
def send(recipient, rendered, message_id, before_data):
|
||||
before_data()
|
||||
self.assertEqual(recipient, self.user['email'])
|
||||
self.assertIn('so far', rendered['subject'])
|
||||
self.assertNotIn('[Test]', rendered['subject'])
|
||||
with patch.object(recaps, 'get_monthly_report', new_callable=AsyncMock, return_value=report), patch.object(mail, 'send_email', side_effect=send):
|
||||
await recaps.process_delivery(store.claim_delivery(time.time()))
|
||||
self.assertEqual(self.delivery(queued['id'])['state'], 'sent')
|
||||
self.assertFalse(store.settings()['enabled'])
|
||||
self.assertFalse(store.subscription(self.user['id'])['automatic_monthly'])
|
||||
with self.assertRaises(recaps.RecapError) as error:
|
||||
recaps.queue_personal(self.user, month, 'manual-2')
|
||||
self.assertEqual(error.exception.status, 429)
|
||||
|
||||
async def test_automatic_opt_out_cancels_scheduled_but_keeps_manual(self):
|
||||
sub, _ = self.subscribe()
|
||||
with store.transaction() as conn:
|
||||
scheduled = store._enqueue(conn, sub, self.report['month'], 'scheduled', 'scheduled-fixture', self.config['public_url'], time.time())
|
||||
manual = recaps.queue_personal(self.user, None, 'manual')
|
||||
store.set_automatic(self.user['id'], False)
|
||||
self.assertEqual(self.delivery(scheduled)['state'], 'cancelled')
|
||||
self.assertEqual(self.delivery(manual['id'])['state'], 'queued')
|
||||
self.assertEqual(store.subscription(self.user['id'])['state'], 'enabled')
|
||||
now = datetime.now(timezone.utc)
|
||||
store.save_settings({**self.config, 'enabled': True}, now)
|
||||
self.assertEqual(store.enqueue_due(now + timedelta(days=40)), 0)
|
||||
|
||||
async def test_changed_identity_cancels_manual_delivery(self):
|
||||
self.subscribe()
|
||||
queued = recaps.queue_personal(self.user, None, 'manual')
|
||||
delivery = store.claim_delivery(time.time())
|
||||
db.set_user_email('viewer', 'changed@example.test')
|
||||
with patch.object(mail, 'send_email') as send:
|
||||
await recaps.process_delivery(delivery)
|
||||
send.assert_not_called()
|
||||
self.assertEqual(self.delivery(queued['id'])['state'], 'cancelled')
|
||||
|
||||
async def test_regular_user_can_only_send_to_self(self):
|
||||
self.subscribe()
|
||||
app = FastAPI(); app.include_router(router.router)
|
||||
app.dependency_overrides[get_current_user] = lambda: {'username': 'viewer', 'role': 'user'}
|
||||
client = TestClient(app)
|
||||
body = {'month': self.report['month'], 'request_id': '11111111-1111-4111-8111-111111111111'}
|
||||
for extra in [{'email': 'other@example.test'}, {'user_id': 42}, {'kind': 'scheduled'}]:
|
||||
self.assertEqual(client.post('/profile/email-recaps/send', json={**body, **extra}).status_code, 422)
|
||||
self.assertEqual(client.post('/profile/email-recaps/send', json=body).status_code, 202)
|
||||
response = client.get('/profile/email-recaps')
|
||||
self.assertEqual(response.headers['cache-control'], 'no-store')
|
||||
self.assertEqual(len(response.json()['deliveries']), 1)
|
||||
|
||||
Reference in New Issue
Block a user