def test_update_relationships(self, db): """ Updating role updates matching relationship descriptions to empty. If I have my role set in my profile as 'foo' and I change it to 'bar', any relationships where I am the elder and the relationship description is 'foo' will be updated to '' (which falls back to profile role). """ rel1 = factories.RelationshipFactory.create(description='foo', from_profile__role='foo') rel2 = factories.RelationshipFactory.create(description='bar', from_profile=rel1.elder) form = forms.EditProfileForm({ 'name': 'New', 'role': 'new' }, instance=rel1.elder) assert form.is_valid() form.save() rel1 = utils.refresh(rel1) rel2 = utils.refresh(rel2) assert rel1.description == '' assert rel2.description == 'bar'
def test_creates_post(self, db): """Actually creates and returns a Post object.""" rel = factories.RelationshipFactory.create() target = 'portfoliyo.model.village.models.timezone.now' with mock.patch(target) as mock_now: mock_now.return_value = datetime.datetime(2012, 9, 17, 6, 25, tzinfo=utc) post = models.Post.create(rel.elder, rel.student, 'Foo\n') assert post.author == rel.elder assert post.student == rel.student assert post.relationship == rel assert post.post_type == 'message' assert post.timestamp == mock_now.return_value assert post.original_text == 'Foo\n' assert post.html_text == 'Foo<br>' assert post.from_sms == False assert post.to_sms == False assert post.meta == {'sms': []} assert utils.refresh(rel.elder).has_posted
def test_subsequent_signup_when_first_needs_name(db): """If first signup needs name, second takes over where it left off.""" phone = '+13216430987' signup = factories.TextSignupFactory.create( family__phone=phone, state=model.TextSignup.STATE.name, student=factories.ProfileFactory.create(), ) factories.RelationshipFactory.create( from_profile=signup.teacher, to_profile=signup.student) factories.RelationshipFactory.create( from_profile=signup.family, to_profile=signup.student) other_teacher = factories.ProfileFactory.create( code='ABCDEF', name='Ms. Doe') reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, 'ABCDEF') assert reply == ( "Ok, thanks! You can text Ms. Doe at this number too. " "And what's your name?" ) new_signup = signup.family.signups.exclude(pk=signup.pk).get() signup = utils.refresh(signup) assert signup.state == model.TextSignup.STATE.done assert new_signup.state == model.TextSignup.STATE.name assert new_signup.teacher == other_teacher assert new_signup.student == signup.student assert new_signup.group is None
def test_sending_sms_flips_to_done(self, db): """If a user in signup process gets a text, we flip them to done.""" rel1 = factories.RelationshipFactory.create( from_profile__name="John Doe", from_profile__phone=None, ) rel2 = factories.RelationshipFactory.create( to_profile=rel1.to_profile, from_profile__phone="+13216540987", from_profile__source_phone="+1333666000", from_profile__user__is_active=True, ) signup = factories.TextSignupFactory.create( teacher=rel1.elder, family=rel2.elder, student=rel1.student, state='kidname', ) target = 'portfoliyo.model.village.models.tasks.send_sms.delay' with mock.patch(target) as mock_send_sms: models.Post.create( rel1.elder, rel1.student, 'Hey dad', profile_ids=[rel2.elder.id], ) mock_send_sms.assert_called_with( "+13216540987", "+1333666000", "Hey dad --John Doe") assert utils.refresh(signup).state == 'done'
def test_activate_user(db): """Receiving SMS from inactive user activates and gives them more info.""" phone = '+13216430987' profile = factories.ProfileFactory.create( user__is_active=False, phone=phone, declined=True) rel = factories.RelationshipFactory.create( from_profile=profile, to_profile__name="Jimmy Doe") # prevent this from being a "no teachers" situation factories.RelationshipFactory.create( from_profile__school_staff=True, from_profile__name='Ms. Johns', to_profile=rel.student, ) with mock.patch('portfoliyo.sms.hook.model.Post.create') as mock_create: reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, 'foo') profile = utils.refresh(profile) assert profile.user.is_active assert not profile.declined mock_create.assert_any_call( None, rel.student, reply, in_reply_to=phone, notifications=False) assert reply == ( "You can text this number " "to talk with Ms. Johns." )
def test_sending_sms_flips_to_done(self, db): """If a user in signup process gets a text, we flip them to done.""" rel1 = factories.RelationshipFactory.create( from_profile__name="John Doe", from_profile__phone=None, ) rel2 = factories.RelationshipFactory.create( to_profile=rel1.to_profile, from_profile__phone="+13216540987", from_profile__source_phone="+1333666000", from_profile__user__is_active=True, ) signup = factories.TextSignupFactory.create( teacher=rel1.elder, family=rel2.elder, student=rel1.student, state='kidname', ) target = 'portfoliyo.model.village.models.tasks.send_sms.delay' with mock.patch(target) as mock_send_sms: models.Post.create( rel1.elder, rel1.student, 'Hey dad', profile_ids=[rel2.elder.id], ) mock_send_sms.assert_called_with("+13216540987", "+1333666000", "Hey dad --John Doe") assert utils.refresh(signup).state == 'done'
def test_active_user_decline(db): """If an active user replies with 'stop', they are marked declined.""" phone = '+13216430987' profile = factories.ProfileFactory.create( user__is_active=True, phone=phone) rel = factories.RelationshipFactory.create(from_profile=profile) with mock.patch('portfoliyo.sms.hook.model.Post.create') as mock_create: reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, 'stop') assert not utils.refresh(profile.user).is_active assert utils.refresh(profile).declined assert reply == ( "No problem! Sorry to have bothered you. " "Text this number anytime to re-start." ) mock_create.assert_any_call(profile, rel.student, "stop", from_sms=True) mock_create.assert_any_call( None, rel.student, reply, in_reply_to=phone, notifications=False)
def test_inactive_user_becomes_active(self, client): """An inactive user who completes a reset becomes active.""" user = factories.UserFactory.create( email='*****@*****.**', is_active=False) form = client.get(self.url(client, user)).forms['set-password-form'] new_password = '******' form['new_password1'] = new_password form['new_password2'] = new_password form.submit(status=302).follow() assert utils.refresh(user).is_active
def test_inactive_user_becomes_active(self, client): """An inactive user who completes a reset becomes active.""" user = factories.UserFactory.create(email='*****@*****.**', is_active=False) form = client.get(self.url(client, user)).forms['set-password-form'] new_password = '******' form['new_password1'] = new_password form['new_password2'] = new_password form.submit(status=302).follow() assert utils.refresh(user).is_active
def test_reverse_add_no_dupe_relationship(self, db): """Adding a group to a student doesn't re-create dupe relationship.""" rel = factories.RelationshipFactory.create() g = factories.GroupFactory.create() rel.student.student_in_groups.add(g) rel.elder.elder_in_groups.add(g) rel = utils.refresh(rel) assert rel.direct assert set(rel.groups.all()) == {g}
def test_no_create_dupe_relationship(self, db): """If a relationship already exists, don't re-create it.""" rel = factories.RelationshipFactory.create() g = factories.GroupFactory.create() g.students.add(rel.student) g.elders.add(rel.elder) rel = utils.refresh(rel) assert rel.direct assert set(rel.groups.all()) == {g}
def test_edit_profile(self, client): """Can edit profile.""" profile = factories.ProfileFactory.create() form = client.get(self.url, user=profile.user).forms['edit-profile-form'] form['name'] = 'New Name' form['role'] = 'New Role' response = form.submit().follow() response.mustcontain('saved') profile = utils.refresh(profile) assert profile.name == u'New Name' assert profile.role == u'New Role'
def test_create(self, db): """Creates a bulk post and posts in individual villages.""" rel = factories.RelationshipFactory() rel2 = factories.RelationshipFactory(from_profile=rel.elder) factories.RelationshipFactory(from_profile=rel.elder) g = factories.GroupFactory() g.students.add(rel.student, rel2.student) post = models.BulkPost.create(rel.elder, g, "Hallo") subs = models.Post.objects.filter(from_bulk=post) exp = set([p.student for p in subs]) assert set([rel.student, rel2.student]) == exp assert {rel, rel2} == set([p.relationship for p in subs]) assert utils.refresh(rel.elder).has_posted
def test_update_relationships(self, db): """ Updating role updates matching relationship descriptions to empty. If I have my role set in my profile as 'foo' and I change it to 'bar', any relationships where I am the elder and the relationship description is 'foo' will be updated to '' (which falls back to profile role). """ rel1 = factories.RelationshipFactory.create( description='foo', from_profile__role='foo') rel2 = factories.RelationshipFactory.create( description='bar', from_profile=rel1.elder) form = forms.EditProfileForm( {'name': 'New', 'role': 'new'}, instance=rel1.elder) assert form.is_valid() form.save() rel1 = utils.refresh(rel1) rel2 = utils.refresh(rel2) assert rel1.description == '' assert rel2.description == 'bar'
def test_code_signup_role(db): """Parent can continue code signup by providing their role.""" phone = '+13216430987' teacher_rel = factories.RelationshipFactory.create( from_profile__school_staff=True, from_profile__name='Jane Doe', from_profile__user__email='*****@*****.**', to_profile__name="Jimmy Doe") parent_rel = factories.RelationshipFactory.create( from_profile__name="John Doe", from_profile__role="", from_profile__phone=phone, from_profile__invited_by=teacher_rel.elder, to_profile=teacher_rel.student, description="", ) factories.TextSignupFactory.create( family=parent_rel.elder, student=parent_rel.student, teacher=teacher_rel.elder, state=model.TextSignup.STATE.relationship, ) with mock.patch('portfoliyo.sms.hook.model.Post.create') as mock_create: reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, "father") assert reply == ( "Last question: what is your name? (So Jane Doe knows who is texting.)") parent = model.Profile.objects.get(phone=phone) signup = parent.signups.get() assert parent.role == "father" assert signup.state == model.TextSignup.STATE.name parent_rel = utils.refresh(parent_rel) assert parent_rel.description == "father" student = teacher_rel.student # and the role is sent on to the village chat as a post mock_create.assert_any_call( parent, student, "father", from_sms=True, notifications=False) # and the automated reply is also sent on to village chat mock_create.assert_any_call( None, student, reply, in_reply_to=phone, notifications=False)
def test_creates_post(self, db): """Actually creates and returns a Post object.""" rel = factories.RelationshipFactory.create() target = 'portfoliyo.model.village.models.timezone.now' with mock.patch(target) as mock_now: mock_now.return_value = datetime.datetime( 2012, 9, 17, 6, 25, tzinfo=utc) post = models.Post.create(rel.elder, rel.student, 'Foo\n') assert post.author == rel.elder assert post.student == rel.student assert post.relationship == rel assert post.post_type == 'message' assert post.timestamp == mock_now.return_value assert post.original_text == 'Foo\n' assert post.html_text == 'Foo<br>' assert post.from_sms == False assert post.to_sms == False assert post.meta == {'sms': []} assert utils.refresh(rel.elder).has_posted
def test_subsequent_group_signup_when_first_needs_student_name(db): """If first signup needs student name, second takes over there.""" phone = '+13216430987' signup = factories.TextSignupFactory.create( family__phone=phone, state=model.TextSignup.STATE.kidname, ) group = factories.GroupFactory.create( code='ABCDEF', owner__name='Ms. Doe') reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, 'ABCDEF') assert reply == ( "Ok, thanks! You can text Ms. Doe at this number too. " "And what's the student's first and last name?" ) new_signup = signup.family.signups.exclude(pk=signup.pk).get() signup = utils.refresh(signup) assert signup.state == model.TextSignup.STATE.done assert new_signup.state == model.TextSignup.STATE.kidname assert new_signup.teacher == group.owner assert new_signup.student is None assert new_signup.group == group
def test_subsequent_signup_with_language(db): """A parent can update their language with their second code.""" phone = '+13216430987' signup = factories.TextSignupFactory.create( family__phone=phone, family__lang_code='en', state=model.TextSignup.STATE.done, student=factories.ProfileFactory.create(), ) factories.RelationshipFactory.create( from_profile=signup.teacher, to_profile=signup.student) factories.RelationshipFactory.create( from_profile=signup.family, to_profile=signup.student) factories.ProfileFactory.create( code='ABCDEF', name='Ms. Doe') with mock.patch('portfoliyo.sms.hook.model.Post.create'): reply = hook.receive_sms(phone, settings.DEFAULT_NUMBER, 'ABCDEF Es') profile = utils.refresh(signup.family) assert profile.lang_code == 'es' assert reply == ( u"¡Ok, gracias! Usted puede texto del Ms. Doe en este número también.")
def test_email_can_be_None(self, db): """Email can be set to None.""" user = factories.UserFactory.create(email=None) assert utils.refresh(user).email == None
def test_email_can_be_long(self, db): """Email can be longer than 75 chars without truncation.""" long_email = ('f' * 75) + '@example.com' user = factories.UserFactory.create(email=long_email) assert utils.refresh(user).email == long_email