def make_share( self, headers, conversation_id, educator_user_id, community_partner_user_id, starting_in_hours=24, location='Somewhere', duration=1, title='Trip to moon', description='Is the moon made of Cheese?', force_past_events=False): if force_past_events: CommunityShareTestCase.FAKE_TIME_SHIFT = 1000 else: CommunityShareTestCase.FAKE_TIME_SHIFT = 0 now = datetime.datetime.utcnow() starting = now + datetime.timedelta(hours=starting_in_hours) ending = now + datetime.timedelta(hours=starting_in_hours + duration) share_data = { 'title': title, 'description': description, 'conversation_id': conversation_id, 'educator_user_id': educator_user_id, 'community_partner_user_id': community_partner_user_id, 'events': [ {'location': location, 'datetime_start': time_format.to_iso8601(starting), 'datetime_stop': time_format.to_iso8601(ending),}, ] } serialized = json.dumps(share_data) rv = self.app.post( '/api/share', headers=headers, data=serialized) assert(rv.status_code == 200) data = json.loads(rv.data.decode('utf8'))['data'] return data
def make_share( self, headers, conversation_id, educator_user_id, community_partner_user_id, starting_in_hours=24, location='Somewhere', duration=1, title='Trip to moon', description='Is the moon made of Cheese?', force_past_events=False, ): if force_past_events: CommunityShareTestCase.FAKE_TIME_SHIFT = 1000 else: CommunityShareTestCase.FAKE_TIME_SHIFT = 0 now = datetime.datetime.utcnow() starting = now + datetime.timedelta(hours=starting_in_hours) ending = now + datetime.timedelta(hours=starting_in_hours + duration) share_data = { 'title': title, 'description': description, 'conversation_id': conversation_id, 'educator_user_id': educator_user_id, 'community_partner_user_id': community_partner_user_id, 'events': [ { 'location': location, 'datetime_start': time_format.to_iso8601(starting), 'datetime_stop': time_format.to_iso8601(ending), }, ] } serialized = json.dumps(share_data) rv = self.app.post('/api/share', headers=headers, data=serialized) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] return data
def statistics(): requester = get_requesting_user() if requester is None: raise Unauthorized() elif not requester.is_administrator: raise Forbidden() else: yesterday = Statistic.date_yesterday() response_data = {'data': {}} for days_ago in range(30): date = yesterday - datetime.timedelta(days=days_ago) stats = Statistic.get_statistics(date) response_data['data'][time_format.to_iso8601(date)] = stats return response_data
def statistics(): requester = get_requesting_user() if requester is None: response = base_routes.make_not_authorized_response() elif not requester.is_administrator: response = base_routes.make_forbidden_response() else: yesterday = Statistic.date_yesterday() response_data = {'data': {}} for days_ago in range(30): date = yesterday - datetime.timedelta(days=days_ago) stats = Statistic.get_statistics(date) response_data['data'][time_format.to_iso8601(date)] = stats response = jsonify(response_data) return response
def test_share(self): # Signup users and confirm emails user_datas = { 'userA': sample_userA, 'userB': sample_userB, 'userC': sample_userC, } user_ids, user_headers = self.create_users(user_datas) user_headers['noone'] = make_headers() searchA_id, searchB_id = self.create_searches(user_ids, user_headers) conversation_data = self.make_conversation( user_headers['userA'], search_id=searchA_id, title='Trip to moon.', userA_id=user_ids['userA'], userB_id=user_ids['userB'], ) conversation_id = conversation_data['id'] # userA creates a share share_data = self.make_share( user_headers['userA'], conversation_id, educator_user_id=user_ids['userA'], community_partner_user_id=user_ids['userB'], ) share_id = share_data['id'] self.assertEqual(len(share_data['events']), 1) # This should send an email to userB that a share has been created. # This also sends an email to the "notify" address. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 2) email = [email for email in mailer.queue if email.to_address == sample_userB['email']][0] mailer.queue.pop() mailer.queue.pop() self.assertEqual(email.to_address, sample_userB['email']) # Check link is valid links = email.find_links() self.assertEqual(len(links), 1) chopped_link = chop_link(links[0]) rv = self.app.get(chopped_link) self.assertEqual(rv.status_code, 200) # We should not be able to get this share if unauthenticated rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['noone']) self.assertEqual(rv.status_code, 401) # Logged on users can access share info # FIXME: Need to check if this should be more private. rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['userC']) self.assertEqual(rv.status_code, 200) # User B should be able to access it. rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['userB']) self.assertEqual(rv.status_code, 200) share_data = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(share_data['id'], share_id) self.assertTrue(share_data['educator_approved']) self.assertFalse(share_data['community_partner_approved']) # Now let's edit the share. share_data = { 'description': 'Is the moon made of Cheese? There is only one way to find out!', } serialized = json.dumps(share_data) # Unauthenticated person should not be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['noone'], data=serialized, ) self.assertEqual(rv.status_code, 401) # User C should not be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userC'], data=serialized, ) self.assertEqual(rv.status_code, 403) # User B should be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] # There should still be one event there. self.assertEqual(len(data['events']), 1) event_id = data['events'][0]['id'] # This should send an email to userA that a share has been edited. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # User B edits it and adds an additional event existing_event = data['events'][0] now = datetime.datetime.utcnow() starting = now + datetime.timedelta(hours=3) ending = now + datetime.timedelta(hours=4) data['events'].append( { 'location': 'Somewhere Else', 'datetime_start': time_format.to_iso8601(starting), 'datetime_stop': time_format.to_iso8601(ending), } ) serialized = json.dumps(data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) data = json.loads(rv.data.decode('utf8'))['data'] ids = set([e['id'] for e in data['events']]) self.assertIn(event_id, ids) self.assertEqual(len(ids), 2) self.assertEqual(rv.status_code, 200) # This should send an email to userA that a share has been edited. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # And who has given approval is switched. self.assertFalse(data['educator_approved']) self.assertTrue(data['community_partner_approved']) # User A can do a put with no changes to approve. serialized = json.dumps(data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userA'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] self.assertTrue(data['educator_approved']) self.assertTrue(data['community_partner_approved']) # This should send an email to userB that changes have been approved. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userB['email']) # Now userB deletes the events share_data = {'events': []} serialized = json.dumps(share_data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(len(data['events']), 0) # User A should have received an email mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # UserA cancels the share rv = self.app.delete('api/share/{0}'.format(share_id), headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) # User B should have received an email. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userB['email'])
def test_statistics(self): user_datas = { 'userA': sample_userA, 'userB': sample_userB, } user_ids, user_headers = self.create_users(user_datas) # userA is not an administrator so we should get forbidden. rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 403) # Make userA an administrator userA = store.session.query(User).filter(User.id == user_ids['userA']).first() userA.is_administrator = True store.session.add(userA) store.session.commit() # Now we should get stats rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] yesterday = datetime.datetime.utcnow().date() - datetime.timedelta(days=1) yesterday_string = time_format.to_iso8601(yesterday) self.assertEqual(stats[yesterday_string]['n_new_users'], 0) # Now create change the creation date of a user so it was yesterday. userA.date_created = datetime.datetime.utcnow() - datetime.timedelta(days=1) store.session.add(userA) store.session.commit() # Add force recalculation of statistics Statistic.update_statistics(yesterday, force=True) # We should get stats and see one new user yesterday. rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(stats[yesterday_string]['n_new_users'], 1) self.assertEqual(stats[yesterday_string]['n_users_started_conversation'], 0) self.assertEqual(stats[yesterday_string]['n_users_did_event'], 0) # Now lets make a conversation and event searchA_id, searchB_id = self.create_searches(user_ids, user_headers) conversation_data = self.make_conversation( user_headers['userA'], search_id=searchA_id, title='Trip to moon.', userA_id=user_ids['userA'], userB_id=user_ids['userB'], ) conversation_id = conversation_data['id'] share_data = self.make_share( user_headers['userA'], conversation_id, educator_user_id=user_ids['userA'], community_partner_user_id=user_ids['userB'], starting_in_hours=-20, force_past_events=True, ) share_id = share_data['id'] eventA_id = share_data['events'][0]['id'] # Pretend conversation was created yesterday. conversation = store.session.query(Conversation) conversation = conversation.filter(Conversation.id == conversation_id) conversation = conversation.first() conversation.date_created -= datetime.timedelta(hours=24) store.session.add(conversation) store.session.commit() # Stats should be appropriately changed. Statistic.update_statistics(yesterday, force=True) rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(stats[yesterday_string]['n_new_users'], 1) self.assertEqual(stats[yesterday_string]['n_users_started_conversation'], 1) # FIXME(seanastephens): What is this assertion and why does it fail? # self.assertEqual(stats[yesterday_string]['n_users_did_event'], 2) # Make sure check_statistics doesn't break Statistic.check_statistics() rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(len(stats.keys()), 30)
def serialize_datetime_stop(self, requester): return time_format.to_iso8601(self.datetime_stop)
def test_share(self): # Signup users and confirm emails user_datas = { 'userA': sample_userA, 'userB': sample_userB, 'userC': sample_userC, } user_ids, user_headers = self.create_users(user_datas) user_headers['noone'] = make_headers() searchA_id, searchB_id = self.create_searches(user_ids, user_headers) conversation_data = self.make_conversation( user_headers['userA'], search_id=searchA_id, title='Trip to moon.', userA_id=user_ids['userA'], userB_id=user_ids['userB'], ) conversation_id = conversation_data['id'] # userA creates a share share_data = self.make_share( user_headers['userA'], conversation_id, educator_user_id=user_ids['userA'], community_partner_user_id=user_ids['userB'], ) share_id = share_data['id'] self.assertEqual(len(share_data['events']), 1) # This should send an email to userB that a share has been created. # This also sends an email to the "notify" address. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 2) email = [ email for email in mailer.queue if email.to_address == sample_userB['email'] ][0] mailer.queue.pop() mailer.queue.pop() self.assertEqual(email.to_address, sample_userB['email']) # Check link is valid links = email.find_links() self.assertEqual(len(links), 1) chopped_link = chop_link(links[0]) rv = self.app.get(chopped_link) self.assertEqual(rv.status_code, 200) # We should not be able to get this share if unauthenticated rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['noone']) self.assertEqual(rv.status_code, 401) # Logged on users can access share info # FIXME: Need to check if this should be more private. rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['userC']) self.assertEqual(rv.status_code, 200) # User B should be able to access it. rv = self.app.get('/api/share/{0}'.format(share_id), headers=user_headers['userB']) self.assertEqual(rv.status_code, 200) share_data = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(share_data['id'], share_id) self.assertTrue(share_data['educator_approved']) self.assertFalse(share_data['community_partner_approved']) # Now let's edit the share. share_data = { 'description': 'Is the moon made of Cheese? There is only one way to find out!', } serialized = json.dumps(share_data) # Unauthenticated person should not be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['noone'], data=serialized, ) self.assertEqual(rv.status_code, 401) # User C should not be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userC'], data=serialized, ) self.assertEqual(rv.status_code, 403) # User B should be able to edit it. rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] # There should still be one event there. self.assertEqual(len(data['events']), 1) event_id = data['events'][0]['id'] # This should send an email to userA that a share has been edited. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # User B edits it and adds an additional event existing_event = data['events'][0] now = datetime.datetime.utcnow() starting = now + datetime.timedelta(hours=3) ending = now + datetime.timedelta(hours=4) data['events'].append({ 'location': 'Somewhere Else', 'datetime_start': time_format.to_iso8601(starting), 'datetime_stop': time_format.to_iso8601(ending), }) serialized = json.dumps(data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) data = json.loads(rv.data.decode('utf8'))['data'] ids = set([e['id'] for e in data['events']]) self.assertIn(event_id, ids) self.assertEqual(len(ids), 2) self.assertEqual(rv.status_code, 200) # This should send an email to userA that a share has been edited. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # And who has given approval is switched. self.assertFalse(data['educator_approved']) self.assertTrue(data['community_partner_approved']) # User A can do a put with no changes to approve. serialized = json.dumps(data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userA'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] self.assertTrue(data['educator_approved']) self.assertTrue(data['community_partner_approved']) # This should send an email to userB that changes have been approved. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userB['email']) # Now userB deletes the events share_data = {'events': []} serialized = json.dumps(share_data) rv = self.app.put( '/api/share/{0}'.format(share_id), headers=user_headers['userB'], data=serialized, ) self.assertEqual(rv.status_code, 200) data = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(len(data['events']), 0) # User A should have received an email mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userA['email']) # UserA cancels the share rv = self.app.delete('api/share/{0}'.format(share_id), headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) # User B should have received an email. mailer = mail.get_mailer() self.assertEqual(len(mailer.queue), 1) email = mailer.pop() self.assertEqual(email.to_address, sample_userB['email'])
def test_statistics(self): user_datas = { 'userA': sample_userA, 'userB': sample_userB, } user_ids, user_headers = self.create_users(user_datas) # userA is not an administrator so we should get forbidden. rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 403) # Make userA an administrator userA = store.session.query(User).filter( User.id == user_ids['userA']).first() userA.is_administrator = True store.session.add(userA) store.session.commit() # Now we should get stats rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] yesterday = datetime.datetime.utcnow().date() - datetime.timedelta( days=1) yesterday_string = time_format.to_iso8601(yesterday) self.assertEqual(stats[yesterday_string]['n_new_users'], 0) # Now create change the creation date of a user so it was yesterday. userA.date_created = datetime.datetime.utcnow() - datetime.timedelta( days=1) store.session.add(userA) store.session.commit() # Add force recalculation of statistics Statistic.update_statistics(yesterday, force=True) # We should get stats and see one new user yesterday. rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(stats[yesterday_string]['n_new_users'], 1) self.assertEqual( stats[yesterday_string]['n_users_started_conversation'], 0) self.assertEqual(stats[yesterday_string]['n_users_did_event'], 0) # Now lets make a conversation and event searchA_id, searchB_id = self.create_searches(user_ids, user_headers) conversation_data = self.make_conversation( user_headers['userA'], search_id=searchA_id, title='Trip to moon.', userA_id=user_ids['userA'], userB_id=user_ids['userB'], ) conversation_id = conversation_data['id'] share_data = self.make_share( user_headers['userA'], conversation_id, educator_user_id=user_ids['userA'], community_partner_user_id=user_ids['userB'], starting_in_hours=-20, force_past_events=True, ) share_id = share_data['id'] eventA_id = share_data['events'][0]['id'] # Pretend conversation was created yesterday. conversation = store.session.query(Conversation) conversation = conversation.filter(Conversation.id == conversation_id) conversation = conversation.first() conversation.date_created -= datetime.timedelta(hours=24) store.session.add(conversation) store.session.commit() # Stats should be appropriately changed. Statistic.update_statistics(yesterday, force=True) rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(stats[yesterday_string]['n_new_users'], 1) self.assertEqual( stats[yesterday_string]['n_users_started_conversation'], 1) # FIXME(seanastephens): What is this assertion and why does it fail? # self.assertEqual(stats[yesterday_string]['n_users_did_event'], 2) # Make sure check_statistics doesn't break Statistic.check_statistics() rv = self.app.get('/api/statistics', headers=user_headers['userA']) self.assertEqual(rv.status_code, 200) stats = json.loads(rv.data.decode('utf8'))['data'] self.assertEqual(len(stats.keys()), 30)