def test_create_stream_if_needed(self) -> None: now = timezone_now() realm = get_realm('zulip') user = self.example_user('hamlet') stream = create_stream_if_needed(realm, "test", invite_only=False, stream_description="Test Description", acting_user=user)[0] self.assertEqual(RealmAuditLog.objects.filter(realm=realm, event_type=RealmAuditLog.STREAM_CREATED, event_time__gte=now, acting_user=user, modified_stream=stream).count(), 1)
def subscribe(self, user_profile: UserProfile, stream_name: str) -> Stream: try: stream = get_stream(stream_name, user_profile.realm) from_stream_creation = False except Stream.DoesNotExist: stream, from_stream_creation = create_stream_if_needed(user_profile.realm, stream_name) bulk_add_subscriptions([stream], [user_profile], from_stream_creation=from_stream_creation) return stream
def test_guest_user_multiple_stream_sender( self, mock_send_future_email: mock.MagicMock, mock_enough_traffic: mock.MagicMock) -> None: othello = self.example_user('othello') hamlet = self.example_user('hamlet') cordelia = self.example_user('cordelia') polonius = self.example_user('polonius') create_stream_if_needed(cordelia.realm, 'web_public_stream', is_web_public=True) self.subscribe(othello, 'web_public_stream') self.subscribe(hamlet, 'web_public_stream') self.subscribe(cordelia, 'web_public_stream') self.subscribe(polonius, 'web_public_stream') one_day_ago = timezone_now() - datetime.timedelta(days=1) Message.objects.all().update(date_sent=one_day_ago) one_hour_ago = timezone_now() - datetime.timedelta(seconds=3600) cutoff = time.mktime(one_hour_ago.timetuple()) senders = ['hamlet', 'cordelia', 'othello', 'desdemona'] self.simulate_stream_conversation('web_public_stream', senders) # Remove RealmAuditoLog rows, so we don't exclude polonius. RealmAuditLog.objects.all().delete() flush_per_request_caches() # When this test is run in isolation, one additional query is run which # is equivalent to # ContentType.objects.get(app_label='zerver', model='userprofile') # This code is run when we call `confirmation.models.create_confirmation_link`. # To trigger this, we call the one_click_unsubscribe_link function below. one_click_unsubscribe_link(polonius, 'digest') with queries_captured() as queries: bulk_handle_digest_email([polonius.id], cutoff) self.assert_length(queries, 9) self.assertEqual(mock_send_future_email.call_count, 1) kwargs = mock_send_future_email.call_args[1] self.assertEqual(kwargs['to_user_ids'], [polonius.id]) new_stream_names = kwargs['context']['new_streams']['plain'] self.assertTrue('web_public_stream' in new_stream_names)
def test_slow_query_log(self, mock_logging_info: Mock) -> None: error_bot = get_system_bot(settings.ERROR_BOT) create_stream_if_needed(error_bot.realm, settings.SLOW_QUERY_LOGS_STREAM) self.log_data['time_started'] = time.time() - self.SLOW_QUERY_TIME write_log_line(self.log_data, path='/socket/open', method='SOCKET', remote_ip='123.456.789.012', requestor_for_logs='unknown', client_name='?') last_message = self.get_last_message() self.assertEqual(last_message.sender.email, "*****@*****.**") self.assertIn("logs", str(last_message.recipient)) self.assertEqual(last_message.topic_name(), "testserver: slow queries") self.assertRegexpMatches(last_message.content, r"123\.456\.789\.012 SOCKET 200 10\.\ds .*")
def test_new_stream_link(self, mock_django_timezone: mock.MagicMock) -> None: cutoff = datetime.datetime(year=2017, month=11, day=1) mock_django_timezone.return_value = datetime.datetime(year=2017, month=11, day=5) cordelia = self.example_user('cordelia') stream_id = create_stream_if_needed(cordelia.realm, 'New stream')[0].id new_stream = gather_new_streams(cordelia, cutoff)[1] expected_html = "<a href='http://zulip.testserver/#narrow/stream/{stream_id}-New-stream'>New stream</a>".format( stream_id=stream_id) self.assertIn(expected_html, new_stream['html'])
def test_slow_queries_worker(self) -> None: error_bot = get_system_bot(settings.ERROR_BOT) fake_client = self.FakeClient() worker = SlowQueryWorker() create_stream_if_needed(error_bot.realm, 'errors') send_mock = patch( 'zerver.worker.queue_processors.internal_send_stream_message') with send_mock as sm, loopworker_sleep_mock as tm: with simulated_queue_client(lambda: fake_client): try: worker.setup() # `write_log_line` is where we publish slow queries to the queue. with patch('zerver.middleware.is_slow_query', return_value=True): write_log_line(log_data=dict(test='data'), requestor_for_logs='*****@*****.**', remote_ip='127.0.0.1', client_name='website', path='/test/', method='GET') worker.start() except AbortLoop: pass self.assertEqual(tm.call_args[0][0], 60) # should sleep 60 seconds sm.assert_called_once() args = [c[0] for c in sm.call_args_list][0] self.assertEqual(args[0], error_bot.realm) self.assertEqual(args[1].email, error_bot.email) self.assertEqual(args[2].name, "errors") self.assertEqual(args[3], "testserver: slow queries") # Testing for specific query times can lead to test discrepancies. logging_info = re.sub(r'\(db: [0-9]+ms/\d+q\)', '', args[4]) self.assertEqual( logging_info, ' 127.0.0.1 GET 200 -1000ms ' ' /test/ ([email protected] via website) ([email protected])\n')
def test_new_stream_link(self) -> None: Stream.objects.all().delete() cutoff = timezone_now() - datetime.timedelta(days=5) cordelia = self.example_user('cordelia') stream = create_stream_if_needed(cordelia.realm, 'New stream')[0] stream.date_created = timezone_now() stream.save() realm = cordelia.realm recent_streams = get_recent_streams(realm, cutoff) stream_count, stream_info = gather_new_streams(realm, recent_streams, can_access_public=True) self.assertEqual(stream_count, 1) expected_html = f"<a href='http://zulip.testserver/#narrow/stream/{stream.id}-New-stream'>New stream</a>" self.assertEqual(stream_info['html'][0], expected_html) # guests don't see our stream stream_count, stream_info = gather_new_streams(realm, recent_streams, can_access_public=False) self.assertEqual(stream_count, 0) self.assertEqual(stream_info['html'], []) # but they do if we make it web public stream.is_web_public = True stream.save() recent_streams = get_recent_streams(realm, cutoff) stream_count, stream_info = gather_new_streams(realm, recent_streams, can_access_public=True) self.assertEqual(stream_count, 1) # Make the stream appear to be older. stream.date_created = timezone_now() - datetime.timedelta(days=7) stream.save() recent_streams = get_recent_streams(realm, cutoff) stream_count, stream_info = gather_new_streams(realm, recent_streams, can_access_public=True) self.assertEqual(stream_count, 0) self.assertEqual(stream_info['html'], [])
def test_notify_realm_of_new_user(self) -> None: realm = get_realm("zulip") new_user = self.example_user("cordelia") admin_realm = get_realm("zulipinternal") admin_realm_signups_stream, created = create_stream_if_needed( admin_realm, "signups") message_count = self.get_message_count() notify_new_user(new_user) self.assertEqual(self.get_message_count(), message_count + 2) message = self.get_second_to_last_message() self.assertEqual(message.recipient.type, Recipient.STREAM) actual_stream = Stream.objects.get(id=message.recipient.type_id) self.assertEqual(actual_stream.name, Realm.INITIAL_PRIVATE_STREAM_NAME) self.assertIn( f"@_**Cordelia, Lear's daughter|{new_user.id}** just signed up for Zulip.", message.content, ) message = self.get_last_message() self.assertEqual(message.recipient.type, Recipient.STREAM) actual_stream = Stream.objects.get(id=message.recipient.type_id) self.assertEqual(actual_stream.name, "signups") self.assertIn( f"Cordelia, Lear's daughter <`{new_user.email}`> just signed up for Zulip. (total:", message.content, ) admin_realm_signups_stream.delete() notify_new_user(new_user) self.assertEqual(self.get_message_count(), message_count + 3) message = self.get_last_message() self.assertEqual(message.recipient.type, Recipient.STREAM) actual_stream = Stream.objects.get(id=message.recipient.type_id) self.assertEqual(actual_stream.name, Realm.INITIAL_PRIVATE_STREAM_NAME) self.assertIn( f"@_**Cordelia, Lear's daughter|{new_user.id}** just signed up for Zulip.", message.content, ) realm.signup_notifications_stream = None realm.save(update_fields=["signup_notifications_stream"]) new_user.refresh_from_db() notify_new_user(new_user) self.assertEqual(self.get_message_count(), message_count + 3)
def test_new_stream_link(self) -> None: Stream.objects.all().delete() cutoff = timezone_now() - datetime.timedelta(days=5) cordelia = self.example_user('cordelia') stream = create_stream_if_needed(cordelia.realm, 'New stream')[0] stream.date_created = timezone_now() stream.save() stream_count, stream_info = gather_new_streams(cordelia, cutoff) self.assertEqual(stream_count, 1) expected_html = f"<a href='http://zulip.testserver/#narrow/stream/{stream.id}-New-stream'>New stream</a>" self.assertEqual(stream_info['html'][0], expected_html) # Make the stream appear to be older. stream.date_created = timezone_now() - datetime.timedelta(days=7) stream.save() stream_count, stream_info = gather_new_streams(cordelia, cutoff) self.assertEqual(stream_count, 0) self.assertEqual(stream_info['html'], [])
def test_scrub_realm(self) -> None: zulip = get_realm("zulip") lear = get_realm("lear") iago = self.example_user("iago") othello = self.example_user("othello") cordelia = self.lear_user("cordelia") king = self.lear_user("king") create_stream_if_needed(lear, "Shakespeare") self.subscribe(cordelia, "Shakespeare") self.subscribe(king, "Shakespeare") Message.objects.all().delete() UserMessage.objects.all().delete() for i in range(5): self.send_stream_message(iago, "Scotland") self.send_stream_message(othello, "Scotland") self.send_stream_message(cordelia, "Shakespeare") self.send_stream_message(king, "Shakespeare") Attachment.objects.filter(realm=zulip).delete() Attachment.objects.create(realm=zulip, owner=iago, path_id="a/b/temp1.txt", size=512) Attachment.objects.create(realm=zulip, owner=othello, path_id="a/b/temp2.txt", size=512) Attachment.objects.filter(realm=lear).delete() Attachment.objects.create(realm=lear, owner=cordelia, path_id="c/d/temp1.txt", size=512) Attachment.objects.create(realm=lear, owner=king, path_id="c/d/temp2.txt", size=512) CustomProfileField.objects.create(realm=lear) self.assertEqual(Message.objects.filter(sender__in=[iago, othello]).count(), 10) self.assertEqual(Message.objects.filter(sender__in=[cordelia, king]).count(), 10) self.assertEqual(UserMessage.objects.filter(user_profile__in=[iago, othello]).count(), 20) self.assertEqual(UserMessage.objects.filter(user_profile__in=[cordelia, king]).count(), 20) self.assertNotEqual(CustomProfileField.objects.filter(realm=zulip).count(), 0) with self.assertLogs(level="WARNING"): do_scrub_realm(zulip, acting_user=None) self.assertEqual(Message.objects.filter(sender__in=[iago, othello]).count(), 0) self.assertEqual(Message.objects.filter(sender__in=[cordelia, king]).count(), 10) self.assertEqual(UserMessage.objects.filter(user_profile__in=[iago, othello]).count(), 0) self.assertEqual(UserMessage.objects.filter(user_profile__in=[cordelia, king]).count(), 20) self.assertEqual(Attachment.objects.filter(realm=zulip).count(), 0) self.assertEqual(Attachment.objects.filter(realm=lear).count(), 2) self.assertEqual(CustomProfileField.objects.filter(realm=zulip).count(), 0) self.assertNotEqual(CustomProfileField.objects.filter(realm=lear).count(), 0) zulip_users = UserProfile.objects.filter(realm=zulip) for user in zulip_users: self.assertTrue(re.search("Scrubbed [a-z0-9]{15}", user.full_name)) self.assertTrue(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email)) self.assertTrue(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.delivery_email)) lear_users = UserProfile.objects.filter(realm=lear) for user in lear_users: self.assertIsNone(re.search("Scrubbed [a-z0-9]{15}", user.full_name)) self.assertIsNone(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.email)) self.assertIsNone(re.search("scrubbed-[a-z0-9]{15}@" + zulip.host, user.delivery_email))
def handle(self, *args: Any, **options: str) -> None: realm = self.get_realm(options) assert realm is not None # Should be ensured by parser stream_name = options["stream_name"] create_stream_if_needed(realm, stream_name, acting_user=None)