def put(self, request, *args, **kwargs): steps_to_update = request.data.copy() user_id = steps_to_update.pop('user_id', None) or request.user.id to_update = { k: bool(v) for k, v in list(steps_to_update.items()) if k in get_onboarding_steps() } if to_update and request.user.id: projection = {k: 1 for k, v in list(to_update.items())} projection['_id'] = 0 passed_steps = c_onboarding_status().find_one( {onboarding.USER_ID: user_id}, projection) or {} for step in to_update: if to_update[step] and not passed_steps.get(step): create_intercom_event(event_name='step-completed', created_at=int( time.mktime(time.localtime())), email=request.user.email, metadata={'step': step}) c_onboarding_status().update_one({onboarding.USER_ID: user_id}, {'$set': to_update}, upsert=True) return RestResponse({'status': 'Ok'}, status=status.HTTP_200_OK) return RestResponse({'status': 'Failed'}, status=status.HTTP_400_BAD_REQUEST)
def test_get_with_user_200(self): c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) response = self.client.get(reverse(self.namespace)) expected_data = { "done": True, } response_data = json.loads(response.content)['data'] for key in response_data.keys(): self.assertSetEqual(set(expected_data), set(response_data[key]))
def test_get_with_user_200(self): c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) response = self.client.get(reverse(self.namespace)) expected_data = { "done": True, } response_data = json.loads(response.content)['data'] for key in list(response_data.keys()): self.assertSetEqual(set(expected_data), set(response_data[key]))
def update_onboarding_step(step, user_id): find_crit = {onboarding.USER_ID: user_id} onboarding_data = c_onboarding_status(use_secondary=True).find_one(find_crit) if not onboarding_data or not onboarding_data.get(step): c_onboarding_status().update_one(find_crit, {'$set': { step: True }}, upsert=True) user = User.objects.filter(id=user_id).first() if user: create_intercom_event( event_name='step-completed', created_at=int(time.mktime(time.localtime())), email=user.email, metadata={'step': step} )
def update_onboarding_step(step, user_id): find_crit = {onboarding.USER_ID: user_id} onboarding_data = c_onboarding_status( use_secondary=True).find_one(find_crit) if not onboarding_data or not onboarding_data.get(step): c_onboarding_status().update_one(find_crit, {'$set': { step: True }}, upsert=True) user = User.objects.filter(id=user_id).first() if user: create_intercom_event(event_name='step-completed', created_at=int(time.mktime( time.localtime())), email=user.email, metadata={'step': step})
def test_put_invalid_keys(self): data_to_update = {'invalid_key': True} c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) ensure_saved = c_onboarding_status().find_one( {onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(ensure_saved, self.data) response = self.client.put(reverse('api:v0:onboarding-status'), data=json.dumps(data_to_update), content_type="application/json") self.assertEqual(response.status_code, 400)
def test_put_invalid_keys(self): data_to_update = {'invalid_key': True} c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) ensure_saved = c_onboarding_status().find_one({onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(ensure_saved, self.data) response = self.client.put( reverse('api:v0:onboarding-status'), data=json.dumps(data_to_update), content_type="application/json" ) self.assertEqual(response.status_code, 400)
def get_onboarding_percentage(user_id): if user_id: status = c_onboarding_status(use_secondary=True).find_one({onboarding.USER_ID: user_id}) or {} if status: steps = [status.get(key, False) for key in get_onboarding_steps()] return round( len(filter(lambda x: x, steps)) / float(len(steps)) * 100, 0 ) return 0
def get_onboarding_percentage(user_id): if user_id: status = c_onboarding_status(use_secondary=True).find_one( {onboarding.USER_ID: user_id}) or {} if status: steps = [status.get(key, False) for key in get_onboarding_steps()] return round( # TODO rewrite it to len([x for x in steps if x]) / float(len(steps)) * 100, ? len(list([x for x in steps if x])) / float(len(steps)) * 100, 0) return 0
def test_put_valid_data(self): data_to_update = {onboarding.STEP_2: True} c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) ensure_saved = c_onboarding_status().find_one( {onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(ensure_saved, self.data) self.assertEqual( self.client.login(username=self.username, password=self.password), True) response = self.client.put(reverse('api:v0:onboarding-status'), data=json.dumps(data_to_update), content_type="application/json") data = self.data.copy() self.assertEqual(response.status_code, 200) data.update(data_to_update) mongo_data = c_onboarding_status().find_one( {onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(mongo_data, data)
def put(self, request, *args, **kwargs): steps_to_update = request.data.copy() user_id = steps_to_update.pop('user_id', None) or request.user.id to_update = { k: bool(v) for k, v in steps_to_update.items() if k in get_onboarding_steps() } if to_update and request.user.id: projection = {k: 1 for k, v in to_update.items()} projection['_id'] = 0 passed_steps = c_onboarding_status().find({onboarding.USER_ID: user_id}, projection) passed_steps = passed_steps[0] if passed_steps else {} for step in to_update: if to_update[step] and not passed_steps.get(step): create_intercom_event( event_name='step-completed', created_at=int(time.mktime(time.localtime())), email=request.user.email, metadata={'step': step} ) c_onboarding_status().update_one({onboarding.USER_ID: user_id}, {'$set': to_update}, upsert=True) return RestResponse({'status': 'Ok'}, status=status.HTTP_200_OK) return RestResponse({'status': 'Failed'}, status=status.HTTP_400_BAD_REQUEST)
def get_onboarding_status_with_settings(user_id): """ Return combined data with the status by on-boarding steps (done: true/false) and settings for according status name Argument: user_id (int): user's id Return: dict with data Example: { "instructor_intro": { "done": true }, "create_course": { "done": true }, "create_courselet": { "done": false }, "review_answers": { "done": true }, "invite_somebody": { "done": true }, "create_thread": { "done": false } } """ onboarding_status = c_onboarding_status().find_one( {onboarding.USER_ID: user_id}, { '_id': 0, 'user_id': 0 }) or {} return { step: { 'done': onboarding_status.get(step, False) } for step in get_onboarding_steps() }
def get_onboarding_status_with_settings(user_id): """ Return combined data with the status by on-boarding steps (done: true/false) and settings for according status name Argument: user_id (int): user's id Return: dict with data Example: { "instructor_intro": { "done": true }, "create_course": { "done": true }, "create_courselet": { "done": false }, "review_answers": { "done": true }, "invite_somebody": { "done": true }, "create_thread": { "done": false } } """ onboarding_status = c_onboarding_status().find_one({onboarding.USER_ID: user_id}, {'_id': 0, 'user_id': 0}) or {} return { step: { 'done': onboarding_status.get(step, False)} for step in get_onboarding_steps() }
def test_put_valid_data(self): data_to_update = {onboarding.STEP_2: True} c_onboarding_status().remove() c_onboarding_status().insert(self.data.copy()) ensure_saved = c_onboarding_status().find_one({onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(ensure_saved, self.data) self.assertEqual(self.client.login(username=self.username, password=self.password), True) response = self.client.put( reverse('api:v0:onboarding-status'), data=json.dumps(data_to_update), content_type="application/json" ) data = self.data.copy() self.assertEqual(response.status_code, 200) data.update(data_to_update) mongo_data = c_onboarding_status().find_one({onboarding.USER_ID: self.user.id}, {'_id': False}) self.assertEqual(mongo_data, data)
def test_wo_user_403(self): c_onboarding_status().remove() self.client.logout() response = self.client.get(reverse(self.namespace)) self.assertEqual(response.status_code, 403)
def test_wo_user_403(self): c_onboarding_status().remove() self.client.logout() response = self.client.get(reverse(self.namespace)) self.assertEqual(response.status_code, 403)