def test_existing_trial_user_new_subscription_payment( self, mocked_date, user=None ): if not user: user = self._make_user( email='*****@*****.**', groups=[Group.by_name('enabled'), Group.by_name('trial')], ) mocked_date.today.return_value = date(2013, 12, 30) view = IPNView(testing.DummyRequest()) view.provider = 'jvzoo' view.params = AttrDict({ 'email': '*****@*****.**', 'fullname': u'Föo Bar', 'trans_type': 'BILL', 'trans_id': 123, 'product_id': 1, }) resp = view.ipn() self.assertEqual(resp, 'Done.') self.assertEqual(user.enabled, True) self.assertEqual(user.trial, False) self.assertEqual(user.valid_to, date(2014, 1, 30)) self.assertEqual(user.last_payment, date(2013, 12, 30)) self.assertEqual(len(user.audit_log_entries), 1) self.assertEqual( user.audit_log_entries[0].event_type.name, u'UserEnabled') self.assertEqual( user.audit_log_entries[0].comment, u'Enabled by jvzoo, transaction id: 123, type: BILL, note: ' u'regular until 2014-01-30', )
def __init__(self, request): self.request = request self.schema = SQLAlchemySchemaNode( User, includes=self.fields, overrides={ 'properties': {'includes': ['key', 'value']}, 'email': {'validator': deferred_user_email_validator}, 'billing_email': { 'validator': deferred_user_billing_email_validator} } ) # we don't like the way ColanderAlchemy renders SA Relationships so # we manually inject a suitable SchemaNode for groups choices = [(group.id, group.name) for group in Group.get_all()] enabled = Group.by_name('enabled') choices.remove((enabled.id, enabled.name)) if not request.user.admin: admins = Group.by_name('admins') choices.remove((admins.id, admins.name)) self.schema.add( node=colander.SchemaNode( colander.Set(), name='groups', missing=[], widget=deform.widget.CheckboxChoiceWidget(values=choices), validator=deferred_groups_validator, ), )
def submit_success(self, appstruct): group = Group( name=appstruct.get('name'), product_id=appstruct.get('product_id'), validity=appstruct.get('validity'), trial_validity=appstruct.get('trial_validity'), addon=appstruct.get('addon'), forward_ipn_to_url=appstruct.get('forward_ipn_to_url'), users=[ User.by_id(user_id) for user_id in appstruct.get('users', []) ], # noqa upgrade_groups=[ Group.by_id(group_id) for group_id in appstruct.get('upgrade_groups', []) ], # noqa properties=[ GroupProperty(key=prop['key'], value=prop['value']) for prop in appstruct.get('properties', []) ], ) Session.add(group) Session.flush() self.request.session.flash(u'Group "{}" added.'.format(group.name)) return HTTPFound( location=self.request.route_path('group_edit', group_id=group.id))
def test_existing_user_cancel_subscription(self, mocked_date): user = self._make_user( email='*****@*****.**', groups=[ Group.by_name('enabled'), Group.by_name('trial'), Group.by_name('monthly'), ]) mocked_date.today.return_value = date(2013, 12, 30) view = IPNView(testing.DummyRequest()) view.provider = 'clickbank' view.params = AttrDict({ 'email': '*****@*****.**', 'trans_type': 'RFND', 'trans_id': 123, 'product_id': 1, }) resp = view.ipn() self.assertEqual(resp, 'Done.') self.assertEqual(user.enabled, False) self.assertEqual(user.valid_to, date(2013, 12, 30)) self.assertEqual(len(user.audit_log_entries), 1) self.assertEqual( user.audit_log_entries[0].event_type.name, u'UserDisabled') self.assertEqual( user.audit_log_entries[0].comment, u'Disabled by clickbank, transaction id: 123, type: RFND, note: ' u'removed from groups: enabled, trial, monthly', )
def test_save_success(self): self.request.context = User.by_id(2) # add a property that will get updated on save_success() self.request.context.set_property(key=u'foo', value=u'var') result = self.view.save_success(self.APPSTRUCT) self.assertIsInstance(result, HTTPFound) self.assertEqual(result.location, '/user/2/') user = User.by_id(2) self.assertEqual(user.email, '*****@*****.**') self.assertTrue(verify('new_secret', user.password)) self.assertEqual(user.fullname, u'Foö Bar') self.assertEqual(user.affiliate, u'Aff') self.assertEqual(user.billing_email, '*****@*****.**') self.assertEqual(user.valid_to, date(2014, 2, 1)) self.assertEqual(user.last_payment, date(2014, 1, 1)) self.assertEqual(user.groups, [Group.by_id(1), Group.by_id(3) ]) # enabled user stays enabled # noqa self.assertEqual(user.get_property('foo'), 'bar') self.assertEqual(user.get_property('baz'), 'bam') self.assertEqual(user.get_property('empty'), None) with self.assertRaises(KeyError): user.get_property('bimt') # removed property self.assertEqual( self.request.session.pop_flash(), [u'User "*****@*****.**" modified.'], )
def __call__(self): warnings = [] if not Group.by_name('admins'): warnings.append('Group "admins" missing.') if not Group.by_name('enabled'): warnings.append('Group "enabled" missing.') if not Group.by_name('trial'): warnings.append('Group "trial" missing.') return warnings
def test_present_choices_widget(self): from pyramid_bimt.models import Group groups = [Group(id=1, name='one'), Group(id=2, name='two')] group = mock.Mock(name='test_group', product_id=1) group.upgrade_groups = groups kw = mock.MagicMock() kw.get.return_value.user.product_group = group widget = self.widget(None, kw) self.assertEqual(widget.values[0], (groups[0].id, groups[0].name)) self.assertEqual(widget.values[1], (groups[1].id, groups[1].name)) self.assertEqual(widget.template, 'upgrade_select')
def test_exclude(self): add_groups() add_users() mailing = _make_mailing( name='foo', groups=[Group.by_name('enabled')], exclude_groups=[Group.by_name('admins'), Group.by_name('staff')], ) self.request.context = mailing self.assertItemsEqual( self.view.recipients, [User.by_email('*****@*****.**')], )
def test_submit_success(self): result = self.view.submit_success(self.APPSTRUCT) self.assertIsInstance(result, HTTPFound) self.assertEqual(result.location, '/portlet/1/edit/') portlet = Portlet.by_id(1) self.assertEqual(portlet.name, 'foo') self.assertEqual(portlet.groups, [Group.by_id(1)]) self.assertEqual(portlet.exclude_groups, [Group.by_id(2)]) self.assertEqual(portlet.position, PortletPositions.below_sidebar.name) self.assertEqual(portlet.weight, 10) self.assertEqual(portlet.html, u'Foo') self.assertEqual(self.request.session.pop_flash(), [u'Portlet "foo" added.'])
def test_existing_regular_user_new_subscription_payment(self): """Test for the "ValueError: list.remove(x): x not in list" bug.""" user = self._make_user( email='*****@*****.**', groups=[Group.by_name('enabled')], ) self.test_existing_trial_user_new_subscription_payment(user=user)
def submit_success(self, appstruct): user = User( email=appstruct.get('email'), fullname=appstruct.get('fullname'), affiliate=appstruct.get('affiliate'), billing_email=appstruct.get('billing_email'), valid_to=appstruct.get('valid_to'), last_payment=appstruct.get('last_payment'), groups=[Group.by_id(group_id) for group_id in appstruct.get('groups', [])], # noqa properties=[UserProperty(key=prop.get('key'), value=prop.get('value')) # noqa for prop in appstruct.get('properties', [])], ) if appstruct.get('password'): # pragma: no branch user.password = encrypt(appstruct['password']) Session.add(user) Session.flush() self.request.registry.notify( UserCreated( self.request, user, appstruct.get('password'), u'Created manually by {}'.format(self.request.user.email) ) ) self.request.session.flash(u'User "{}" added.'.format(user.email)) return HTTPFound( location=self.request.route_path('user_view', user_id=user.id))
def test_non_product_group_cant_have_upgrade_groups(self): from pyramid_bimt.tests.test_group_model import _make_group self.request.context = _make_group(name='test', product_id=None) view = self.view(self.request) self.assertIn(self.request.context, Group.get_all().all()) self.assertIsNone(view.schema.get('upgrade_groups'))
def test_submit_success(self): result = self.view.submit_success(self.APPSTRUCT) self.assertIsInstance(result, HTTPFound) self.assertEqual(result.location, '/mailing/1/edit/') mailing = Mailing.by_id(1) self.assertEqual(mailing.name, 'foo') self.assertEqual(mailing.groups, [Group.by_id(1)]) self.assertEqual(mailing.exclude_groups, [Group.by_id(2)]) self.assertEqual(mailing.trigger, MailingTriggers.never.name) self.assertEqual(mailing.days, 30) self.assertEqual(mailing.subject, u'Foö') self.assertEqual(mailing.body, u'Bär') self.assertEqual(self.request.session.pop_flash(), [u'Mailing "foo" added.'])
def __init__(self, request): chosen_assets.need() self.request = request self.schema = SQLAlchemySchemaNode(Mailing, includes=self.fields) # we don't like the way ColanderAlchemy renders SA Relationships so # we manually inject a suitable SchemaNode for groups choices = [(group.id, group.name) for group in Group.get_all()] self.schema.add_before( 'trigger', node=colander.SchemaNode( colander.Set(), name='groups', missing=[], widget=deform.widget.CheckboxChoiceWidget(values=choices), ), ) self.schema.add_before( 'trigger', node=colander.SchemaNode( colander.Set(), name='exclude_groups', missing=[], widget=deform.widget.CheckboxChoiceWidget(values=choices), ), )
def upgrade_subscription_success(self, appstruct): old_group = self.request.user.product_group new_group = Group.by_id( appstruct['change_subscription']['upgrade_subscription']) try: receipt = self._change_clickbank_subscription(new_group) except ClickbankException as exc: comment = ( u'Your upgrade has not completed successfully. Support team ' 'has been notified and they are looking into the problem.') self.request.session.flash(comment) self.request.registry.notify( UserSubscriptionChangeFailed(self.request, self.request.user, comment=comment)) logger.exception(exc) return HTTPFound(location=self.request.path_url) self.request.user.groups.remove(old_group) self.request.user.groups.append(new_group) comment = (u'Your subscription ({}) has been upgraded ' 'from {} to {}.'.format(receipt, old_group.name, new_group.name)) self.request.user.set_property('upgrade_completed', True) self.request.session.flash(comment) self.request.registry.notify( UserSubscriptionChanged(self.request, self.request.user, comment=comment)) return HTTPFound(location=self.request.path_url)
def save_success(self, appstruct): group = self.request.context group.name = appstruct.get('name') group.product_id = appstruct.get('product_id') group.validity = appstruct.get('validity') group.trial_validity = appstruct.get('trial_validity') group.addon = appstruct.get('addon') group.forward_ipn_to_url = appstruct.get('forward_ipn_to_url') group.users = [ User.by_id(user_id) for user_id in appstruct.get('users', []) ] # noqa group.upgrade_groups = [ Group.by_id(group_id) for group_id in appstruct.get('upgrade_groups', []) ] # noqa # remove properties that are not present in appstruct for prop in copy.copy(group.properties): if prop.key not in [p['key'] for p in appstruct['properties']]: group.properties.remove(prop) # update/create properties present in appstruct for prop in appstruct['properties']: if group.get_property(prop['key'], None) is not None: group.set_property(key=prop['key'], value=prop['value']) else: group.properties.append( GroupProperty(key=prop['key'], value=prop['value'])) self.request.session.flash(u'Group "{}" modified.'.format(group.name)) return HTTPFound( location=self.request.route_path('group_edit', group_id=group.id))
def setUp(self): self.config = testing.setUp() initTestingDB(groups=True) Group.by_id(1).product_id = 'old_id' Session.flush() self.request = testing.DummyRequest()
def add_users(): """Init the '*****@*****.**' and '*****@*****.**' user accounts.""" with transaction.manager: admins = Group.by_name('admins') staff = Group.by_name('staff') enabled = Group.by_name('enabled') trial = Group.by_name('trial') # Create the admin user account admin = User( email=u'*****@*****.**', password=SECRET_ENC, fullname=u'Ädmin', properties=[ UserProperty(key=u'bimt', value=u'on'), ], ) admin.groups.append(admins) admin.groups.append(enabled) Session.add(admin) # Create the staff member account staff_member = User( email=u'*****@*****.**', password=SECRET_ENC, fullname=u'Stäff Member', properties=[ UserProperty(key=u'bimt', value=u'on'), ], ) staff_member.groups.append(enabled) staff_member.groups.append(staff) Session.add(staff_member) # Create the normal user account one = User( email=u'*****@*****.**', billing_email=u'*****@*****.**', password=SECRET_ENC, fullname=u'Öne Bar', properties=[ UserProperty(key=u'bimt', value=u'on'), ], ) one.groups.append(enabled) one.groups.append(trial) Session.add(one)
def __getitem__(self, key): group = Group.by_id(key) if group: group.__parent__ = self group.__name__ = key return group else: raise KeyError
def test_save_success(self): self.request.context = Mailing.by_id(1) result = self.view.save_success(self.APPSTRUCT) self.assertIsInstance(result, HTTPFound) self.assertEqual(result.location, '/mailing/1/edit/') mailing = Mailing.by_id(1) self.assertEqual(mailing.name, 'bar') self.assertEqual(mailing.groups, [Group.by_id(1), Group.by_id(2)]) self.assertEqual(mailing.exclude_groups, [Group.by_id(3)]) self.assertEqual(mailing.trigger, MailingTriggers.after_created.name) self.assertEqual(mailing.days, 7) self.assertEqual(mailing.subject, u'Bär') self.assertEqual(mailing.body, u'Bän') self.assertEqual(self.request.session.pop_flash(), [u'Mailing "bar" modified.'])
def _make_group( id=1, name='foo', ): return Group( id=id, name=name, )
def test_group_cant_be_upgrade_group_to_itself(self): from pyramid_bimt.tests.test_group_model import _make_group self.request.context = _make_group(name='test1', product_id=1) view = self.view(self.request) self.assertIn(self.request.context, Group.get_all().all()) self.assertNotIn((str( (self.request.context.id)), self.request.context.name), view.schema.get('upgrade_groups').widget.values)
def test_use_billing_email(self, ClickbankAPI): self.request.registry.settings['bimt.clickbank_dev_key'] = 'dev' self.request.registry.settings['bimt.clickbank_api_key'] = 'key' self.request.user.product_group.product_id = 'foo' self.request.user.email = '*****@*****.**' self.request.user.billing_email = None self.view._change_clickbank_subscription( Group(id=1, name='bar', product_id='baz')) ClickbankAPI.return_value.change_user_subscription.assert_called_with( '*****@*****.**', 'foo', 'baz') self.request.user.email = '*****@*****.**' self.request.user.billing_email = '*****@*****.**' self.view._change_clickbank_subscription( Group(id=1, name='bar', product_id='baz')) ClickbankAPI.return_value.change_user_subscription.assert_called_with( '*****@*****.**', 'foo', 'baz')
def test_save_success(self): self.request.context = Portlet.by_id(1) result = self.view.save_success(self.APPSTRUCT) self.assertIsInstance(result, HTTPFound) self.assertEqual(result.location, '/portlet/1/edit/') portlet = Portlet.by_id(1) self.assertEqual(portlet.name, 'bar') self.assertEqual(portlet.groups, [Group.by_id(2), Group.by_id(3)]) self.assertEqual(portlet.exclude_groups, [ Group.by_id(4), ]) self.assertEqual(portlet.position, PortletPositions.above_content.name) self.assertEqual(portlet.weight, -10) self.assertEqual(portlet.html, u'Bar') self.assertEqual(self.request.session.pop_flash(), [u'Portlet "bar" modified.'])
def save_success(self, appstruct): portlet = self.request.context portlet.name = appstruct['name'] portlet.groups = [ Group.by_id(group_id) for group_id in appstruct['groups'] ] # noqa portlet.exclude_groups = [ Group.by_id(group_id) for group_id in appstruct['exclude_groups'] ] # noqa portlet.position = appstruct['position'] portlet.weight = appstruct['weight'] portlet.html = appstruct['html'] self.request.session.flash(u'Portlet "{}" modified.'.format( portlet.name)) return HTTPFound(location=self.request.route_path( 'portlet_edit', portlet_id=portlet.id))
def _make_ipn_group(): group = Group( name='monthly', product_id=1, validity=31, trial_validity=7, ) Session.add(group) return group
def test_override_ordered_by(self): _make_group(name='foo') _make_group(name='bar') _make_group(name='baz') groups = Group.get_all(order_by='id').all() self.assertEqual(len(groups), 3) self.assertEqual(groups[0].name, 'foo') self.assertEqual(groups[1].name, 'bar') self.assertEqual(groups[2].name, 'baz')
def test_non_admin_and_non_admins(self): from pyramid_bimt.views.user import deferred_groups_validator self.request.user.admin = False cstruct = [ str(Group.by_name('staff').id), ] validator = deferred_groups_validator(None, {'request': self.request}) self.assertFalse(validator(None, cstruct))
def ipn(self): """The main IPN handler, called by the IPN service.""" # skip over to-be-ignored products if self.params.product_id in self.request.registry.settings.get( 'bimt.products_to_ignore', '').split(','): logger.info('The product is listed on the ignore list: {}'.format( self.params.product_id)) return 'Done.' # try to find an existing user with given email user = User.by_email(self.params.email) if not user: user = User.by_billing_email(self.params.email) # create a new user if no existing user found if not user: password = generate() user = User( email=self.params.email, billing_email=self.params.email, password=encrypt(password), fullname=u'{}'.format(self.params.fullname), affiliate=u'{}'.format(self.params.get('affiliate', '')), ) Session.add(user) comment = COMMENT.format( u'Created', self.provider, self.params.trans_id, self.params.trans_type, '', ) logger.info(comment) self.request.registry.notify( UserCreated(self.request, user, password, comment)) # find a group that is used for given product group = Group.by_product_id(self.params.product_id) if not group: raise ValueError('Cannot find group with product_id "{}"'.format( self.params.product_id)) # perform IPN transaction actions self.ipn_transaction(user, group) # send request with same parameters to the URL specified on group if group.forward_ipn_to_url: requests.post( group.forward_ipn_to_url, params=self.request.POST, ) logger.info('IPN re-posted to {}.'.format( group.forward_ipn_to_url)) logger.info('IPN done.') return 'Done.'
def test_ordered_by_name_by_default(self): _make_group(name='foo') _make_group(name='bar') _make_group(name='baz') groups = Group.get_all().all() self.assertEqual(len(groups), 3) self.assertEqual(groups[0].name, 'bar') self.assertEqual(groups[1].name, 'baz') self.assertEqual(groups[2].name, 'foo')