test_user.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. """
  4. 用户需要测试的场景
  5. * 扫入,正常看到所有个人信息
  6. * 充值
  7. * 启动设备
  8. * 直接付钱 启动设备
  9. """
  10. import json
  11. from urlparse import urlparse, parse_qs, ParseResult
  12. import pytest
  13. from apilib.utils_json import JsonResponse, json_dumps
  14. from apilib.monetary import VirtualCoin
  15. from apps.web.core.adapter.commonPulse import CommonPulseAdapter
  16. from apps.web.user.views import cn
  17. from apps.web.utils import ErrorResponseRedirect
  18. from apps.web.user import UserAuthState
  19. from apps.web.core.utils import JsonErrorResponse
  20. from common import url_fn, MY_USER_FIXTURE, json_is_the_same, is_concurrently_safe
  21. def user_login_url_lack_parameter():
  22. return ErrorResponseRedirect(error = u'错误的二维码,可能是二维码损坏,建议直接投币,或者联系工作人员进行维修')
  23. #: ignore hosts, we only care about endpoints
  24. def url_eq(a, b):
  25. assert isinstance(a, str) and isinstance(b, str), 'a and b has to be Url(str)'
  26. parsed_a, parsed_b = urlparse(a), urlparse(b)
  27. ignore_keys = ['t']
  28. def qs(pr):
  29. # type: (ParseResult)->dict
  30. return {k: v for k, v in parse_qs(pr.query).iteritems() if k not in ignore_keys}
  31. return parsed_a.path == parsed_b.path and qs(parsed_a) == qs(parsed_b)
  32. ################
  33. ## User Model
  34. ################
  35. def test_user_get_or_create_via_wechat():
  36. from apps.web.user.models import MyUser
  37. payload = {}
  38. assert MyUser.get_or_create_via_wechat(**payload) is None
  39. ################
  40. ## Auth related
  41. ################
  42. _foreign_gateway_uri_map = {
  43. 'wechat': "https://open.weixin.qq.com/connect/oauth2/authorize",
  44. 'alipay': "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm"
  45. }
  46. @pytest.mark.parametrize("client_name", ['wechat', 'alipay'])
  47. def test_userLogin(wechat_user_client, alipay_user_client, device, dealer, agent, client_name):
  48. _client_map = {'wechat': wechat_user_client, 'alipay': alipay_user_client}
  49. from apps.web.user.views import userLogin
  50. userLogin_url = url_fn(userLogin)
  51. client = _client_map[client_name]
  52. get = client.get
  53. #: lack params user login
  54. assert url_eq(get(userLogin_url()).url, user_login_url_lack_parameter().url)
  55. #: normal situation
  56. response = get(userLogin_url(l = device.logicalCode))
  57. assert _foreign_gateway_uri_map[client_name] in response.url
  58. def test_baseAccess(wechat_client, device, mocker, user, agent, manager, wechat_managerial_app,
  59. default_wechat_payment_app):
  60. from apps.web.user.views import wechatAuthUser
  61. url = url_fn(wechatAuthUser)
  62. #: 如果不带参数,必定报错
  63. assert assert_redirected_to_error_page(wechat_client.get(url).url)
  64. state_by_dev = UserAuthState.by_dev(devNo = device['devNo'])
  65. from apps.web.core.auth.wechat import WechatAuthBridge
  66. mocker.patch.object(WechatAuthBridge, 'authorize', return_value = user.openId)
  67. response = wechat_client.get(url(payload = WechatAuthBridge.encode_state(state_by_dev.to_json()), code = 'CODE'))
  68. assert user.update(avatar = '', nickname = '')
  69. assert _foreign_gateway_uri_map['wechat'] in response.url
  70. assert user.update(avatar = 'something', nickname = 'someone')
  71. response = wechat_client.get(url(payload = WechatAuthBridge.encode_state(state_by_dev.to_json()), code = 'CODE'))
  72. assert _foreign_gateway_uri_map['wechat'] in response.url
  73. assert user.get_collection().update_one(
  74. {'_id': user.id},
  75. {'$set':
  76. dict(avatar = 'something',
  77. nickname = 'someone',
  78. managerialAppId = wechat_managerial_app.appid,
  79. managerialOpenId = 'test_managerial_openId')
  80. })
  81. response = wechat_client.get(url(payload = WechatAuthBridge.encode_state(state_by_dev.to_json()), code = 'CODE'))
  82. assert _foreign_gateway_uri_map['wechat'] in response.url
  83. assert user.get_collection().update_one(
  84. {'_id': user.id},
  85. {'$set':
  86. dict(avatar = 'something',
  87. nickname = 'someone',
  88. managerialAppId = default_wechat_payment_app.appid,
  89. managerialOpenId = 'test_managerial_openId')
  90. })
  91. response = wechat_client.get(url(payload = WechatAuthBridge.encode_state(state_by_dev.to_json()), code = 'CODE'))
  92. assert 'user/index.html' in response.url
  93. def test_managerAccess(wechat_client, device, mocker, user, agent, manager):
  94. from apps.web.user.views import wechatManagerAuthUser
  95. url = url_fn(wechatManagerAuthUser)
  96. #: 如果不带参数,必定报错
  97. assert assert_redirected_to_error_page(wechat_client.get(url).url)
  98. def test_wxpayBaseAccess(wechat_client, device, mocker, user, agent, manager):
  99. from apps.web.user.views import wxpayBaseAccess
  100. url = url_fn(wxpayBaseAccess)
  101. #: 如果不带参数,必定报错
  102. assert assert_redirected_to_error_page(wechat_client.get(url).url)
  103. #################
  104. ### wxpay gateway
  105. #################
  106. def test_wxpayGateway_recharge(wechat_user_client, device, sole_group, mocker, agent, default_wechat_payment_app):
  107. from apps.web.user.views import wxpayGateway
  108. wxpayGateway_url = url_fn(wxpayGateway)
  109. post = wechat_user_client.post_json
  110. cached_group = sole_group.cached
  111. rule_dict = cached_group['ruleDict']
  112. payload = {
  113. 'attachParas': {},
  114. 'ruleId': 1,
  115. 'type': '',
  116. 'forced': 1
  117. }
  118. response = post(wxpayGateway_url(), payload)
  119. assert json_is_the_same(response.content,
  120. JsonErrorResponse(description = u'该设备未开通网络支付,请投币或者联系客服(1008)').content)
  121. payload = {
  122. 'attachParas': {},
  123. 'ruleId': rule_dict.keys()[0],
  124. 'type': '',
  125. 'forced': 1,
  126. 'devNo': device.devNo
  127. }
  128. #: device is default set to offline
  129. assert json.loads(post(wxpayGateway_url(), payload).content)['result'] == 103
  130. invalid_rule_id = next(str(_) for _ in xrange(1000) if _ not in map(int, rule_dict.keys()))
  131. payload = {
  132. 'attachParas': {},
  133. 'ruleId': invalid_rule_id,
  134. 'type': '',
  135. 'forced': 1,
  136. 'devNo': device.devNo
  137. }
  138. from apps.web.core.payment.wechat import WechatPaymentGateway
  139. mocker.patch.object(CommonPulseAdapter, 'check_dev_status', return_value = None)
  140. assert post(wxpayGateway_url(), payload).content == json_dumps({'result': 0, 'description': u'组内未找到所提供ruleId'})
  141. payload = {
  142. 'attachParas': {},
  143. 'ruleId': rule_dict.keys()[0],
  144. 'type': '',
  145. 'forced': 1,
  146. 'devNo': device.devNo
  147. }
  148. mocker.patch.object(WechatPaymentGateway, 'generate_js_payment_signature', return_value = {})
  149. assert json.loads(post(wxpayGateway_url(), payload).content) == {'result': 1, 'description': 'SUCCESS',
  150. 'payload': {}}
  151. def test_wxpayGateway_chargeCardWithCardNo(wechat_user_client, device, sole_group, mocker):
  152. pass
  153. def test_wxpayGateway_chargeCardWithDevNo(wechat_user_client, device, sole_group, mocker):
  154. pass
  155. ### wechatPayNotify
  156. ### dev side info
  157. def test_equipmentPara(wechat_user_client, device):
  158. from apps.web.user.views import equipmentPara
  159. url = url_fn(equipmentPara)
  160. assert wechat_user_client.get(url).json()['result'] == 0
  161. assert wechat_user_client.get(url(devNo = device.devNo)).json()['result'] == 1
  162. def test_userBalance(wechat_user_client):
  163. from apps.web.user.views import userBalance
  164. userBalance_url = url_fn(userBalance)
  165. response = wechat_user_client.get(userBalance_url()) # type: JsonResponse
  166. assert response.status_code == 200
  167. assert json_is_the_same(
  168. response.content,
  169. json_dumps({
  170. 'result': 1,
  171. 'description': '',
  172. 'payload':
  173. {
  174. 'balance': MY_USER_FIXTURE['balance'],
  175. 'overallBalance': MY_USER_FIXTURE['balance'],
  176. 'currencyCoins': MY_USER_FIXTURE['balance']
  177. }
  178. })
  179. )
  180. ### Ad related
  181. def test_adAccess(client, wechat_user_client, device):
  182. from apps.web.user.views import adAccess
  183. url = url_fn(adAccess)
  184. assert client.get(url()).status_code == 302
  185. wechat_user_client.cookies['devNo'] = device.devNo
  186. response = wechat_user_client.get(url())
  187. assert response.status_code == 302
  188. assert url_eq(response.url, ErrorResponseRedirect(error = cn(u'找不到广告ID')).url)
  189. ### Promotion
  190. ### 主要测试并发场景
  191. def test_getPromotionalCoins(wechat_user_client, onsale, device, user):
  192. from apps.web.user.views import getPromotionalCoins
  193. url = url_fn(getPromotionalCoins)
  194. balance = user.balance
  195. assert is_concurrently_safe(lambda:
  196. wechat_user_client.get(
  197. url(logicalCode = device.logicalCode, onsaleId = str(onsale.id))).json())
  198. assert (user.reload().balance - balance) == VirtualCoin(onsale.detailDict.get('coins', 0))
  199. def test_getPromotionalDuration(wechat_user_client, onsale, device, mocker):
  200. from apps.web.user.views import getPromotionalDuration
  201. from apps.web.core.networking import MessageSender
  202. url = url_fn(getPromotionalDuration)
  203. mocker.patch.object(MessageSender, 'send', return_value = {'rst': 0})
  204. assert is_concurrently_safe(
  205. lambda: wechat_user_client.get(url(logicalCode = device.logicalCode, onsaleId = str(onsale.id))).json())
  206. def test_submitFeedback(wechat_user_client, device):
  207. import random
  208. from apps.web.user.views import submitFeedback
  209. from apps.web.constant import FEEDBACK_TYPE
  210. payload = {
  211. 'phone': '13112233122',
  212. 'logicalCode': device.logicalCode,
  213. 'coins': 1,
  214. 'feedType': random.choice(FEEDBACK_TYPE.choices()),
  215. 'imgList': [],
  216. 'description': 'test',
  217. }
  218. url = url_fn(submitFeedback)
  219. response = wechat_user_client.post_json(url, payload)
  220. assert response.json()['result'] == 1
  221. assert is_concurrently_safe(lambda: wechat_user_client.post_json(url, payload).json())
  222. ########################
  223. # Testing about promo #
  224. ########################