A webapp/form for people to join pEp coop. Fork of Cultural Commons Collecting Society (C3S) SCE
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_membership_application.py 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests the c3smembership.data.repository.share_repository package.
  4. """
  5. import datetime
  6. import re
  7. import transaction
  8. import unittest
  9. from pyramid import testing
  10. from sqlalchemy import engine_from_config
  11. from sqlalchemy.sql import func
  12. from webtest import TestApp
  13. from c3smembership import main
  14. from c3smembership.data.model.base import (
  15. DBSession,
  16. Base,
  17. )
  18. from c3smembership.models import (
  19. C3sStaff,
  20. Group,
  21. C3sMember,
  22. )
  23. class MailerDummy(object):
  24. def __init__(self):
  25. self._email = None
  26. def send(self, email):
  27. self._email = email
  28. def get_email(self):
  29. return self._email
  30. class GetMailerDummy(object):
  31. def __init__(self):
  32. self._mailer = MailerDummy()
  33. def __call__(self, request):
  34. return self._mailer
  35. class DateTimeDummy(object):
  36. def __init__(self, now):
  37. self._now = now
  38. def now(self):
  39. return self._now
  40. class MembershipApplicationTest(unittest.TestCase):
  41. def setUp(self):
  42. my_settings = {
  43. 'sqlalchemy.url': 'sqlite:///:memory:',
  44. 'api_auth_token': u"SECRETAUTHTOKEN",
  45. 'c3smembership.url': u'localhost',
  46. 'testing.mail_to_console': u'false',
  47. }
  48. self.config = testing.setUp()
  49. app = main({}, **my_settings)
  50. self.get_mailer = GetMailerDummy()
  51. app.registry.get_mailer = self.get_mailer
  52. app.registry.membership_application.datetime = DateTimeDummy(
  53. datetime.datetime(2018, 4, 26, 12, 23, 34))
  54. engine = engine_from_config(my_settings)
  55. DBSession.configure(bind=engine)
  56. Base.metadata.create_all(engine)
  57. with transaction.manager:
  58. # a group for accountants/staff
  59. accountants_group = Group(name=u"staff")
  60. DBSession.add(accountants_group)
  61. DBSession.flush()
  62. # staff personnel
  63. staffer1 = C3sStaff(
  64. login=u"rut",
  65. password=u"berries",
  66. email=u"noreply@c3s.cc",
  67. )
  68. staffer1.groups = [accountants_group]
  69. DBSession.add(accountants_group)
  70. DBSession.add(staffer1)
  71. DBSession.flush()
  72. self.testapp = TestApp(app)
  73. def tearDown(self):
  74. testing.tearDown()
  75. DBSession.close()
  76. DBSession.remove()
  77. def _login(self):
  78. """
  79. Log into the membership backend
  80. """
  81. res = self.testapp.get('/login', status=200)
  82. self.failUnless('login' in res.body)
  83. form = res.form
  84. form['login'] = 'rut'
  85. form['password'] = 'berries'
  86. res = form.submit('submit', status=302)
  87. def _validate_dashboard_redirect(self, res):
  88. """
  89. Validate that res is redirecting to the dashboard
  90. """
  91. res = res.follow() # being redirected to dashboard with parameters
  92. self.__validate_dashboard(res)
  93. def _validate_dashboard(self, res):
  94. """
  95. Validate that res is the dashboard
  96. """
  97. self.failUnless('Dashboard' in res.body)
  98. @classmethod
  99. def _response_to_bare_text(cls, res):
  100. html = res.normal_body
  101. # remove JavaScript
  102. html = re.sub(re.compile('<script.*</script>'), '', html)
  103. # remove all tags
  104. html = re.sub(re.compile('<.*?>'), '', html)
  105. # remove html characters like &nbsp;
  106. html = re.sub(re.compile('&[A-Za-z]+;'), '', html)
  107. return html
  108. def test_membership_application(self):
  109. """
  110. Test the membership application process.
  111. 1. Enter applicant data to application form
  112. 2. Verify entered data and confirm
  113. 3. Verify sent confirmation email
  114. 4. Confirm email address via confirmation link
  115. 5. Login to backend
  116. 6. Verify applicant's detail page
  117. 7. Set payment received
  118. 8. Set signature received
  119. 9. Make member
  120. 10. Verify member details
  121. """
  122. self.testapp.reset()
  123. # 1. Enter applicant data to application form
  124. res = self.testapp.get('/', status=200)
  125. properties = {
  126. 'firstname': u'Sönke',
  127. 'lastname': u'Blømqvist',
  128. 'email': u'soenke@example.com',
  129. 'address1': u'℅ Big Boss',
  130. 'address2': u'Håkanvägen 12',
  131. 'postcode': u'ABC1234',
  132. 'city': u'Stockholm',
  133. 'year': u'1980',
  134. 'month': u'01',
  135. 'day': u'02',
  136. 'name_of_colsoc': u'Svenska Tonsättares Internationella Musikbyrå',
  137. 'num_shares': u'15',
  138. 'password': u'worst password ever chosen',
  139. 'password-confirm': u'worst password ever chosen',
  140. }
  141. for key, value in properties.iteritems():
  142. res.form[key] = value
  143. res.form['country'].select(text=u'Sweden')
  144. res.form['membership_type'].value__set(u'normal')
  145. res.form['other_colsoc'].value__set(u'yes')
  146. res.form['got_statute'].checked = True
  147. res.form['got_dues_regulations'].checked = True
  148. res = res.form.submit(u'submit', status=302)
  149. res = res.follow()
  150. # 2. Verify entered data and confirm
  151. body = self._response_to_bare_text(res)
  152. self.assertTrue('First Name: Sönke' in body)
  153. self.assertTrue('Last Name: Blømqvist' in body)
  154. self.assertTrue('Email Address: soenke@example.com' in body)
  155. self.assertTrue('Address Line 1: ℅ Big Boss' in body)
  156. self.assertTrue('Address Line 2: Håkanvägen 12' in body)
  157. self.assertTrue('Postal Code: ABC1234' in body)
  158. self.assertTrue('City: Stockholm' in body)
  159. self.assertTrue('Country: SE' in body)
  160. self.assertTrue('Date of Birth: 1980-01-02' in body)
  161. self.assertTrue('Type of Membership:normal' in body)
  162. self.assertTrue('Member of other Collecting Society: yes' in body)
  163. self.assertTrue('Membership(s): Svenska Tonsättares Internationella Musikbyrå' in body)
  164. self.assertTrue('Number of Shares: 15' in body)
  165. self.assertTrue('Cost of Shares (50 € each): 750 €' in body)
  166. res = res.forms[1].submit(status=200)
  167. # 3. Verify sent confirmation email
  168. mailer = self.get_mailer(None)
  169. email = mailer.get_email()
  170. self.assertEqual(email.recipients, ['soenke@example.com'])
  171. self.assertEqual(email.subject, 'C3S: confirm your email address and load your PDF')
  172. # 4. Confirm email address via confirmation link
  173. match = re.search(
  174. 'localhost(?P<url>[^\s]+)',
  175. email.body)
  176. self.assertTrue(match is not None)
  177. res = self.testapp.get(
  178. match.group('url'),
  179. status=200)
  180. self.assertTrue(u'password in order to verify your email' in res.body)
  181. res.form['password'] = 'worst password ever chosen'
  182. res = res.form.submit(u'submit', status=200)
  183. # 5. Login to backend
  184. self.testapp.reset()
  185. self._login()
  186. # 6. Verify applicant's detail page
  187. member_id = DBSession.query(func.max(C3sMember.id)).scalar()
  188. res = self.testapp.get('/detail/{0}'.format(member_id), status=200)
  189. body = self._response_to_bare_text(res)
  190. self.assertTrue('firstname Sönke' in body)
  191. self.assertTrue('lastname Blømqvist' in body)
  192. self.assertTrue('email soenke@example.com' in body)
  193. self.assertTrue('email confirmed? Yes' in body)
  194. self.assertTrue('address1 ℅ Big Boss' in body)
  195. self.assertTrue('address2 Håkanvägen 12' in body)
  196. self.assertTrue('postcode ABC1234' in body)
  197. self.assertTrue('city Stockholm' in body)
  198. self.assertTrue('country SE' in body)
  199. self.assertTrue('date_of_birth 1980-01-02' in body)
  200. self.assertTrue('membership_accepted No' in body)
  201. self.assertTrue('entity type Person' in body)
  202. self.assertTrue('membership type normal' in body)
  203. self.assertTrue('member_of_colsoc Yes' in body)
  204. self.assertTrue('name_of_colsoc Svenska Tonsättares Internationella Musikbyrå' in body)
  205. self.assertTrue('date_of_submission ' in body)
  206. self.assertTrue('signature received? Nein' in body)
  207. self.assertTrue('signature confirmed (mail sent)?No' in body)
  208. self.assertTrue('payment received? Nein' in body)
  209. self.assertTrue('payment confirmed?No' in body)
  210. self.assertTrue('# shares total: 15' in body)
  211. # TODO:
  212. # - code
  213. # - locale, set explicitly and test both German and English
  214. # - date of submission
  215. # 7. Set payment received
  216. res = self.testapp.get(
  217. '/switch_pay/{0}'.format(member_id),
  218. headers={'Referer': 'asdf'},
  219. status=302)
  220. res = res.follow()
  221. body = self._response_to_bare_text(res)
  222. self.assertTrue('payment received? Ja' in body)
  223. self.assertTrue('payment reception date 2018-04-26 12:23:34' in body)
  224. # 8. Set signature received
  225. res = self.testapp.get(
  226. '/switch_sig/{0}'.format(member_id),
  227. headers={'Referer': 'asdf'},
  228. status=302)
  229. res = res.follow()
  230. body = self._response_to_bare_text(res)
  231. self.assertTrue('signature received? Ja' in body)
  232. self.assertTrue('signature reception date2018-04-26 12:23:34' in body)
  233. # 9. Make member
  234. res = self.testapp.get(
  235. '/make_member/{0}'.format(member_id),
  236. headers={'Referer': 'asdf'},
  237. status=200)
  238. res.form['membership_date'] = '2018-04-27'
  239. res = res.form.submit('submit', status=302)
  240. res = res.follow()
  241. # 10. Verify member details
  242. membership_number = C3sMember.get_next_free_membership_number() - 1
  243. body = self._response_to_bare_text(res)
  244. self.assertTrue('membership_accepted Yes' in body)
  245. self.assertTrue(
  246. 'membership_number {0}'.format(membership_number) in body)
  247. self.assertTrue('membership_date 2018-04-27' in body)
  248. self.assertTrue('# shares total: 15' in body)
  249. self.assertTrue('1 package(s)' in body)
  250. self.assertTrue('15 shares (2018-04-27)' in body)