def test_user_update_ignores_blank_email(self): first = 'firsty' last = 'lastington' new_password = '******' username = '******' original_password = '******' user = BadgeUser(username=username, is_active=True) user.set_password(original_password) user.save() UserRecipientIdentifier.objects.create( type=UserRecipientIdentifier.IDENTIFIER_TYPE_URL, identifier='http://testurl.com/123', verified=True, user=user) self.client.login(username=username, password=original_password) self.assertUserLoggedIn() TermsVersion.objects.create(version=1, short_description='terms 1') response = self.client.put('/v1/user/profile', { 'first_name': first + ' Q.', 'last_name': last, 'email': None }, format='json') self.assertEqual(response.status_code, 200)
def test_unverified_unprimary_email_sends_confirmation(self): """ If there is only one email, and it's not primary, set it as primary. If it's not verified, send a verification. """ user = BadgeUser(email="*****@*****.**", first_name="Test", last_name="User") user.save() email = CachedEmailAddress(email=user.email, user=user, verified=False, primary=False) email.save() user2 = BadgeUser(email="*****@*****.**", first_name="Error", last_name="User") user2.save() self.assertEqual(BadgeUser.objects.count(), 2) call_command('clean_email_records') email_record = CachedEmailAddress.objects.get(user=user) self.assertTrue(email_record.primary) self.assertEqual(len(mail.outbox), 1) self.assertEqual(BadgeUser.objects.count(), 1)
def test_user_can_agree_to_terms(self): first = 'firsty' last = 'lastington' new_password = '******' username = '******' original_password = '******' email = '*****@*****.**' user = BadgeUser(username=username, is_active=True, email=email) user.set_password(original_password) user.save() self.client.login(username=username, password=original_password) self.assertUserLoggedIn() TermsVersion.objects.create(version=1, short_description='terms 1') response = self.client.put( '/v1/user/profile', { 'first_name': first, 'last_name': last, 'password': new_password, 'current_password': original_password, 'latest_terms_version': 1 }) self.assertEqual(response.status_code, 200)
def test_email_added_for_user_missing_one(self): user = BadgeUser(email="*****@*****.**", first_name="Test", last_name="User") user.save() self.assertFalse(CachedEmailAddress.objects.filter(user=user).exists()) user2 = BadgeUser(email="*****@*****.**", first_name="Test2", last_name="User") user2.save() email2 = CachedEmailAddress(user=user2, email="*****@*****.**", verified=False, primary=True) email2.save() call_command('clean_email_records') email_record = CachedEmailAddress.objects.get(user=user) self.assertFalse(email_record.verified) self.assertTrue(email_record.emailconfirmation_set.exists()) self.assertEqual(len(mail.outbox), 1)
def test_autocreated_user_signup(self): """ Sometimes admins have a need to manually create users and grant them auth tokens where their primary email is marked verified, but no password is set. For these users, the signup flow should proceed normally. """ badgrapp = BadgrApp.objects.first() badgrapp.ui_login_redirect = 'http://testui.test/auth/login/' badgrapp.email_confirmation_redirect = 'http://testui.test/auth/login/' badgrapp.save() user = BadgeUser(email='*****@*****.**') user.save() email = CachedEmailAddress.cached.create(user=user, email=user.email, verified=True) user_data = { 'first_name': 'Usery', 'last_name': 'McUserface', 'password': '******', 'email': user.email } response = self.client.post('/v1/user/profile', user_data) self.assertEqual(response.status_code, 201) self.assertEqual(len(mail.outbox), 1) verify_url = re.search("(?P<url>/v2/[^\s]+)", mail.outbox[0].body).group("url") response = self.client.get(verify_url[:-5]) self.assertEqual(response.status_code, 302) self.assertNotIn(user_data['first_name'], response._headers['location'][1]) response = self.client.get(verify_url) self.assertEqual(response.status_code, 302) self.assertIn(user_data['first_name'], response._headers['location'][1]) user = BadgeUser.cached.get(email=user.email) self.assertIsNotNone(user.password) self.client.logout() self.client.login(username=user.username, password=user_data['password']) response = self.client.get('/v1/user/profile') self.assertEqual(response.data['first_name'], user_data['first_name'])
def test_user_can_change_profile(self): first = 'firsty' last = 'lastington' new_password = '******' username = '******' original_password = '******' email = '*****@*****.**' user = BadgeUser(username=username, is_active=True, email=email) user.set_password(original_password) user.save() self.client.login(username=username, password=original_password) self.assertUserLoggedIn() response = self.client.put( '/v1/user/profile', { 'first_name': first, 'last_name': last, 'password': new_password, 'current_password': original_password }) self.assertEqual(response.status_code, 200) self.assertEqual(first, response.data.get('first_name')) self.assertEqual(last, response.data.get('last_name')) self.client.logout() self.client.login(username=username, password=new_password) self.assertUserLoggedIn() self.assertEqual(len(mail.outbox), 1) response = self.client.put('/v1/user/profile', { 'first_name': 'Barry', 'last_name': 'Manilow' }) self.assertEqual(response.status_code, 200) self.assertEqual('Barry', response.data.get('first_name')) third_password = '******' response = self.client.put('/v1/user/profile', { 'password': third_password, 'current_password': new_password }) self.assertEqual(response.status_code, 200) self.client.logout() self.client.login(username=username, password=third_password) self.assertUserLoggedIn()
def test_user_can_change_profile(self): first = 'firsty' last = 'lastington' new_password = '******' username = '******' original_password = '******' email = '*****@*****.**' user = BadgeUser(username=username, is_active=True, email=email) user.set_password(original_password) user.save() self.client.login(username=username, password=original_password) self.assertUserLoggedIn() response = self.client.put('/v1/user/profile', { 'first_name': first, 'last_name': last, 'password': new_password, 'current_password': original_password }) self.assertEqual(response.status_code, 200) self.assertEqual(first, response.data.get('first_name')) self.assertEqual(last, response.data.get('last_name')) self.client.logout() self.client.login(username=username, password=new_password) self.assertUserLoggedIn() self.assertEqual(len(mail.outbox), 1) response = self.client.put('/v1/user/profile', { 'first_name': 'Barry', 'last_name': 'Manilow' }) self.assertEqual(response.status_code, 200) self.assertEqual('Barry', response.data.get('first_name')) third_password = '******' response = self.client.put('/v1/user/profile', { 'password': third_password, 'current_password': new_password }) self.assertEqual(response.status_code, 200) self.client.logout() self.client.login(username=username, password=third_password) self.assertUserLoggedIn()
def test_autocreated_user_signup(self): """ Sometimes admins have a need to manually create users and grant them auth tokens where their primary email is marked verified, but no password is set. For these users, the signup flow should proceed normally. """ badgrapp = BadgrApp.objects.first() badgrapp.ui_login_redirect = 'http://testui.test/auth/login/' badgrapp.email_confirmation_redirect = 'http://testui.test/auth/login/' badgrapp.save() user = BadgeUser( email='*****@*****.**' ) user.save() email = CachedEmailAddress.cached.create(user=user, email=user.email, verified=True) user_data = { 'first_name': 'Usery', 'last_name': 'McUserface', 'password': '******', 'email': user.email } response = self.client.post('/v1/user/profile', user_data) self.assertEqual(response.status_code, 201) self.assertEqual(len(mail.outbox), 1) verify_url = re.search("(?P<url>/v2/[^\s]+)", mail.outbox[0].body).group("url") response = self.client.get(verify_url[:-5]) self.assertEqual(response.status_code, 302) self.assertNotIn(user_data['first_name'], response._headers['location'][1]) response = self.client.get(verify_url) self.assertEqual(response.status_code, 302) self.assertIn(user_data['first_name'], response._headers['location'][1]) user = BadgeUser.cached.get(email=user.email) self.assertIsNotNone(user.password) self.client.logout() self.client.login(username=user.username, password=user_data['password']) response = self.client.get('/v1/user/profile') self.assertEqual(response.data['first_name'], user_data['first_name'])
class PathwayApiTests(SetupIssuerHelper, BadgrTestCase): def setUp(self): cache.clear() super(PathwayApiTests, self).setUp() # instructor self.instructor = BadgeUser(username='******', email='*****@*****.**') self.instructor.set_password('secret') self.instructor.save() self.instructor.user_permissions.add( Permission.objects.get(codename="add_issuer")) CachedEmailAddress(email='*****@*****.**', verified=True, primary=True, user=self.instructor).save() self.assertTrue( self.client.login(username='******', password='******'), "Instructor can log in") # issuer issuer_data = { 'name': 'Unit Test Issuer', 'description': "Issuer from unit test", 'url': "http://example.test", 'email': "*****@*****.**", } response = self.client.post(reverse('v1_api_issuer_list'), issuer_data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created an issuer") self.assertTrue(response.data['slug'], "Received an issuer with a slug") self.issuer = response.data # make a default badgeclass self.badgeclass = self.setup_badgeclass(issuer=Issuer.cached.get( entity_id=self.issuer.get('slug'))) def test_can_create_pathway(self): pathway_data = { 'name': "Test Career Pathway", 'description': "Students pathway through the testing career", } response = self.client.post(reverse( 'pathway_list', kwargs={'issuer_slug': self.issuer.get('slug')}), pathway_data, format='json') pathway = response.data self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created pathway") # Plumber # plumbing badges with open( os.path.join(TOP_DIR, 'apps', 'issuer', 'testfiles', 'guinea_pig_testing_badge.png')) as badge_image: response = self.client.post( reverse('v1_api_badgeclass_list', kwargs={'slug': self.issuer.get('slug')}), { 'name': "Plumber", 'description': "You plumb now", 'criteria': "Learn what it is to be a plumber", 'image': badge_image, }) self.assertEqual(response.status_code, 201) plumber_badge = response.data badge_image.seek(0) response = self.client.post( reverse('v1_api_badgeclass_list', kwargs={'slug': self.issuer.get('slug')}), { 'name': "Intro Plumbing Badge", 'description': "You learn to plumb", 'criteria': "learn plumbing basics", 'image': badge_image, }) self.assertEqual(response.status_code, 201) intro_plumbing_badge = response.data badge_image.seek(0) response = self.client.post( reverse('v1_api_badgeclass_list', kwargs={'slug': self.issuer.get('slug')}), { 'name': "Advanced Plumbing 1 Badge", 'description': "You plumb good 1", 'criteria': "advanced plumbing method 1", 'image': badge_image, }) self.assertEqual(response.status_code, 201) adv1_plumbing_badge = response.data badge_image.seek(0) response = self.client.post( reverse('v1_api_badgeclass_list', kwargs={'slug': self.issuer.get('slug')}), { 'name': "Advanced Plumbing 2 Badge", 'description': "You plumb good 2", 'criteria': "advanced plumbing method 2", 'image': badge_image, }) self.assertEqual(response.status_code, 201) adv2_plumbing_badge = response.data response = self.client.post( reverse('pathway_element_list', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug') }), { 'parent': pathway['rootElement'], 'name': 'Plumber', 'description': 'You can plumb things for people.', 'completionBadge': plumber_badge['json']['id'], }, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created pathway element") plumber_element = response.data # Intro to Plumbing response = self.client.post(reverse( 'pathway_element_list', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug') }), { 'parent': plumber_element['@id'], 'name': 'Intro to Plumbing', 'description': 'You learn the basics of plumbing.', 'requirements': { '@type': 'BadgeJunction', 'junctionConfig': { '@type': 'Conjunction', 'requiredNumber': 1, }, 'badges': [intro_plumbing_badge['json']['id']], } }, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created pathway element") intro_plumbing_element = response.data # Advanced Plumbing (testing sending a json string for requirements) response = self.client.post(reverse( 'pathway_element_list', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug') }), { 'parent': plumber_element['@id'], 'name': 'Advanced Plumbing', 'description': 'You learn all about plumbing.', 'requirements': json.dumps({ '@type': 'BadgeJunction', 'junctionConfig': { '@type': 'Disjunction', 'requiredNumber': 1, }, 'badges': [adv1_plumbing_badge['json']['id']], }) }, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created pathway element") adv_plumbing_element = response.data adv_instance = PathwayElement.objects.get( slug=adv_plumbing_element['slug']) self.assertEqual( len(adv_instance.cached_badges()), 1, "One BadgeClass is now associated with the new element.") adv_plumbing_element.update({ 'requirements': { '@type': 'BadgeJunction', 'junctionConfig': { '@type': 'Disjunction', 'requiredNumber': 1, }, 'badges': [ adv1_plumbing_badge['json']['id'], adv2_plumbing_badge['json']['id'] ] } }) response = self.client.put(reverse('pathway_element_detail', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug'), 'element_slug': adv_plumbing_element.get('slug') }), adv_plumbing_element, format='json') self.assertEqual(response.status_code, 200) self.assertEqual(len(adv_instance.cached_badges()), 2, "The new BadgeClass has been added.") # update requirements plumber_element.update({ 'requirements': { '@type': 'ElementJunction', 'junctionConfig': { '@type': 'Conjunction', 'requiredNumber': 2, }, 'elements': [intro_plumbing_element['@id'], adv_plumbing_element['@id']], } }) response = self.client.put(reverse('pathway_element_detail', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug'), 'element_slug': plumber_element.get('slug') }), plumber_element, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK, "Updated pathway element") updated_plumber_element = response.data # Teacher response = self.client.post(reverse( 'pathway_element_list', kwargs={ 'issuer_slug': self.issuer.get('slug'), 'pathway_slug': pathway.get('slug') }), { 'parent': pathway['rootElement'], 'name': 'Teacher', 'description': 'You can teach people things.', 'ordering': 1, 'alignmentUrl': "http://unit.fake.test", }, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Created pathway element") teacher_element = response.data """ def test_can_update_pathway_groups(self): """ group_data = { 'name': 'Group of Testing', 'description': 'A group used for testing.' } response = self.client.post( '/v2/issuers/{}/recipient-groups'.format(self.issuer.get('slug')), group_data) group_slug = response.data.get('slug') update_data = {'groups': [response.data.get('@id')]} response = self.client.put( '/v2/issuers/{}/pathways/{}'.format(self.issuer.get('slug'), pathway.get('slug')), update_data) self.assertEqual(response.status_code, 200) self.assertEqual( response.data.get('groups')[0].get('slug'), group_slug)