def test_cloudflare_solution_fail_infinity(set_mock, as_guest, intercept): cfdata = _get_cf_data() set_mock({ '/': cfdata['cf_mock'], '/login/': cfdata['cf_mock'], cfdata['answer_url']: cfdata['cf_mock'], # В сравнении с предыдущим тестом облом вот тут }) calls = {'page': 0, 'solve': 0} @intercept('/') @intercept('/login/') def get_page(data, headers): calls['page'] += 1 @intercept(cfdata['answer_url']) def cf_solve(data, headers): calls['solve'] += 1 # И вот тут user = UserTest(security_ls_key='N/A', session_id='N/A', avoid_cf=True) with pytest.raises(api.TabunError) as excinfo: user.urlread('/') assert excinfo.value.code == 503 assert calls == {'page': 10, 'solve': 9} assert user.sleeps == [9, 4.0 * 9] assert user.extra_cookies == {'__cfduid': cfdata['cookvalue1']} assert user.session_id == 'N/A' assert user.security_ls_key == 'N/A'
def test_login_ok(set_mock, as_guest, user): set_mock({'/login/ajax-login': '******'}) assert user.username is None assert user.login('test', '123456') is None testutil.guest_mode = False assert user.update_userinfo(user.urlopen('/').read()) == 'test' assert user.username == 'test'
def test_edit_post_ok(form_intercept, set_mock, user, blog_id, blog, result_url, draft, tags, forbid_comment): set_mock({ '/topic/edit/1/': (None, { 'headers': {'location': result_url}, 'status': 302, 'status_msg': 'Found' } )}) @form_intercept('/topic/edit/1/') def topic_edit(data, headers): assert data.get('blog_id') == [text(blog_id if blog_id is not None else 0).encode('utf-8')] assert data.get('security_ls_key') == [b'0123456789abcdef0123456789abcdef'] assert data.get('topic_title') == ['Т0'.encode('utf-8')] assert data.get('topic_text') == ['Б1'.encode('utf-8')] assert data.get('topic_tags') == ['Т2, Т3'.encode('utf-8')] if draft: assert data.get('submit_topic_save') == ['Сохранить в черновиках'.encode('utf-8')] else: assert data.get('submit_topic_publish') == ['Опубликовать'.encode('utf-8')] if forbid_comment: assert data.get('topic_forbid_comment') == [b'1'] else: assert 'topic_forbid_comment' not in data result = user.edit_post(1, blog_id, 'Т0', 'Б1', tags, forbid_comment, draft=draft) assert result == (blog, 1)
def test_user_preloaded_cookies_and_login(set_mock): set_mock({'/': ('404.html', {'status': 404, 'status_msg': 'Not Found'})}) user = UserTest('test', phpsessid='abcdef9876543210abcdef9876543210', security_ls_key='0123456789abcdef0123456789abcdef') assert user.username == 'test' assert user.phpsessid == 'abcdef9876543210abcdef9876543210' assert user.security_ls_key == '0123456789abcdef0123456789abcdef' assert user.key is None
def test_session_id_renamed_authorized(set_mock): class OtherTestUser(UserTest): session_cookie_name = 'PHPSESSID' set_mock({'/': (None, {'headers': {'Set-Cookie': ['PHPSESSID=abcdef9876543210abcdef9876543210; path=/']}})}) user = OtherTestUser() assert user.phpsessid == 'abcdef9876543210abcdef9876543210'
def test_get_more_activity(user, set_mock): answer = '{"iStreamLastId":"15000","result":%DATA%,"events_count":11,"sMsgTitle":"","sMsg":"","bStateError":false}' answer = answer.replace('%DATA%', json.dumps(load_file('activity_items.html', template=False).decode('utf-8'))) set_mock( { '/stream/get_more_all/': (None, { 'data': answer.encode('utf-8'), 'headers': {'Content-Type': 'application/json'}, }) } ) items_data = json.loads(load_file('activity_items.json', template=False).decode('utf-8')) last_id, items = user.get_more_activity() assert last_id == 15000 # assert len(items) == len(items_data) for data, item in zip(items_data, items): for key, value in data.items(): if key == "date": assert time.strftime("%Y-%m-%d %H:%M", item.date) == value else: assert getattr(item, key) == value
def test_login_fail(set_mock, as_guest, user): set_mock({'/login/ajax-login': '******'}) assert user.username is None with pytest.raises(api.TabunResultError): user.login('test', '123456') assert user.username is None assert user.update_userinfo(user.urlopen('/').read()) is None assert user.username is None
def test_login_request(set_mock, form_intercept, as_guest, user): set_mock({'/login/ajax-login': '******'}) @form_intercept('/login/ajax-login') def login(data, headers): assert data.get('login') == ['test'] assert data.get('password') == ['123456'] assert data.get('security_ls_key') == [user.security_ls_key] user.login('test', '123456')
def test_session_id_renamed_authorized(set_mock): extra = {'headers': {'Set-Cookie': ['PHPSESSID=abcdef9876543210abcdef9876543210; path=/']}} set_mock({ '/': ('index.html', extra), '/login/': ('index.html', extra), }) user = UserTest(session_cookie_name='PHPSESSID') assert user.session_id == 'abcdef9876543210abcdef9876543210'
def test_get_posts_profile_data_ok(user, set_mock): set_mock({'/profile/test/created/topics/': 'profile_topics.html'}) post_data = json.loads(load_file('profile_topics.json', template=False).decode('utf-8')) posts = list(reversed(user.get_posts('/profile/test/created/topics/'))) assert len(posts) == len(post_data) for data, post in zip(post_data, posts): assert post.post_id == data['post_id'] assert_data(post, data)
def test_user_preloaded_cookies(set_mock): set_mock({'/': ('404.html', {'status': 404, 'status_msg': 'Not Found'})}) phpsessid = 'abcdef9876543210abcdef9876543210' security_ls_key = '0123456789abcdef0123456789abcdef' key = '00000000000000000000000000000000' user = UserTest(phpsessid=phpsessid, security_ls_key=security_ls_key, key=key) assert user.username is None assert user.phpsessid == phpsessid assert user.security_ls_key == security_ls_key assert user.key == key
def test_get_profile(user, set_mock): set_mock({'/profile/test/': 'profile.html'}) profile = user.get_profile('test') assert profile.user_id == 666 assert profile.username == 'test' assert profile.realname == 'Фамилия Имя' assert profile.skill == 777.77 assert profile.rating == 666.66 assert profile.userpic == '//cdn.everypony.ru/storage/01/54/04/2014/02/28/avatar_100x100.png' assert profile.foto == '//cdn.everypony.ru/storage/01/54/04/2014/02/28/236ad9.jpg' assert profile.gender is None # TODO: more tests assert time.strftime('%Y-%m-%d', profile.birthday) == '1971-02-02' assert time.strftime('%Y-%m-%d %H:%M', profile.registered) == '2012-03-07 03:15' assert time.strftime('%Y-%m-%d %H:%M', profile.last_activity) == '2016-05-22 20:30' # TODO: can be None assert frozenset(profile.blogs) == frozenset(('owner', 'admin', 'moderator', 'member')) assert profile.blogs['owner'] == [] assert profile.blogs['admin'] == [('news', 'Срочно в номер')] assert profile.blogs['moderator'] == [] assert profile.blogs['member'] == [('shipping', 'Все о шиппинге'), ('RPG', 'РПГ7. Воюем, живем, любим.'), ('borderline', 'На грани')] assert profile.description is not None assert profile.raw_description == 'Обо мне. Сломанный код: <a href="' assert profile.rating_vote_count == 37 assert profile.counts == { 'comments': None, 'favourites': 0, 'favourites_comments': None, 'favourites_posts': None, 'friends': 3, 'notes': None, 'posts': None, 'publications': 8697, } assert profile.full is True assert profile.contacts == [ ('phone', None, '79001234567'), ('mail', 'mailto:почта@example.com', 'почта@example.com'), ('skype', 'skype:скайп', 'скайп'), ('icq', 'http://www.icq.com/people/about_me.php?uin=7777777', '7777777'), ('www', 'http://президент.рф', 'президент.рф'), ('twitter', 'http://twitter.com/твиттер/', 'твиттер'), ('facebook', 'http://facebook.com/фейсбук', 'фейсбук'), ('vkontakte', 'http://vk.com/вк', 'вк'), ('odnoklassniki', 'http://www.odnoklassniki.ru/profile/ок/', 'ок'), ] assert profile.context['http_host'] == 'https://tabun.everypony.ru' assert profile.context['url'] == 'https://tabun.everypony.ru/profile/test/' assert profile.context['can_vote'] is False assert profile.context['vote_value'] == 1 assert profile.context['username'] == 'test' # Да, я прописал голос за самого себя :D assert profile.context['note'] == '< > & " \'\ntest' assert profile.context['can_edit_note'] is True
def test_add_comment_ok(form_intercept, set_mock, user): set_mock({'/blog/ajaxaddcomment/': (None, {'data': b'{"sCommentId": 1, "sMsgTitle": "", "sMsg": "", "bStateError": false}'})}) @form_intercept('/blog/ajaxaddcomment/') def add_comment(data, headers): assert headers.get('content-type', '').startswith(b'multipart/form-data; boundary=-') assert data.get('security_ls_key') == [b'0123456789abcdef0123456789abcdef'] assert data.get('cmt_target_id') in ([b'1'], [b'2']) assert data.get('comment_text') == ['тест'.encode('utf-8')] assert data.get('reply') == ([b'0'] if data['cmt_target_id'][0] == b'1' else [b'1']) assert user.comment(1, 'тест') == 1 assert user.comment(1, 'тест', reply=0) == 1
def test_get_activity_livestreet(user, set_mock): set_mock({'/stream/all/': 'activity_ls.html'}) items_data = json.loads(load_file('activity_items.json', template=False).decode('utf-8')) last_id, items = user.get_activity() assert last_id == 15000 # assert len(items) == len(items_data) for data, item in zip(items_data, items): for key, value in data.items(): if key == "date": assert time.strftime("%Y-%m-%d %H:%M", item.date) == value else: assert getattr(item, key) == value
def test_edit_comment_ok(form_intercept, set_mock, user): set_mock({'/ajax/comment/edit/': ( None, {'data': '{"newText": "тест2", "notice": null, "sMsgTitle": null, "sMsg": "Комментарий изменён", "bStateError": false}'.encode('utf-8')}, )}) @form_intercept('/ajax/comment/edit/') def edit_comment(data, headers): assert headers.get('content-type', '').startswith(b'multipart/form-data; boundary=-') assert data.get('security_ls_key') == [b'0123456789abcdef0123456789abcdef'] assert data.get('idComment') == [b'777'] assert data.get('newText') == ['тест2'.encode('utf-8')] assert data.get('setLock') == [b'0'] assert user.edit_comment(777, 'тест2') == ('тест2', 'Комментарий изменён', None)
def test_cloudflare_solution_ok_again(set_mock, as_guest, intercept): # Отличие от предыдущего теста в том, что печеньки уже стоят заранее cfdata = _get_cf_data() set_mock({ '/': cfdata['cf_mock'], '/login/': cfdata['cf_mock'], cfdata['answer_url']: cfdata['cf_mock_solved'], }) calls = {'page': 0, 'solve': 0} @intercept('/') @intercept('/login/') def get_page(data, headers): calls['page'] += 1 @intercept(cfdata['answer_url']) def cf_solve(data, headers): calls['solve'] += 1 set_mock({ '/': 'index.html', '/login/': 'login.html', }) user = UserTest(security_ls_key='N/A', session_id='abcdef9876543210abcdef9876543210', avoid_cf=True) user.extra_cookies.update({ '__cfduid': cfdata['cookvalue1'], 'cf_clearance': 'foobarblablablathisisoldcookie', }) resp = user.urlopen('/') assert resp.code == 200 user.update_userinfo(resp.read()) assert calls == {'page': 2, 'solve': 1} assert user.sleeps == [1, 4.0] assert user.extra_cookies == { '__cfduid': cfdata['cookvalue1'], 'cf_clearance': cfdata['cookvalue2'], } assert user.session_id == 'abcdef9876543210abcdef9876543210' assert user.security_ls_key == '0123456789abcdef0123456789abcdef'
def test_get_profile_topics(user, set_mock): set_mock({'/profile/test/created/topics/': 'profile_topics.html'}) profile = user.get_profile(url='/profile/test/created/topics/') assert profile.user_id == 666 assert profile.username == 'test' assert profile.realname == 'Фамилия Имя' assert profile.skill == 777.77 assert profile.rating == 666.66 assert profile.userpic is None assert profile.foto == '//cdn.everypony.ru/storage/01/54/04/2014/02/28/236ad9.jpg' assert profile.gender is None assert profile.birthday is None assert profile.registered is None assert profile.last_activity is None assert frozenset(profile.blogs) == frozenset(('owner', 'admin', 'moderator', 'member')) assert profile.blogs['owner'] == [] assert profile.blogs['admin'] == [] assert profile.blogs['moderator'] == [] assert profile.blogs['member'] == [] assert profile.description is None assert profile.raw_description is None assert profile.rating_vote_count == 37 assert profile.counts == { 'comments': 8696, 'favourites': 0, 'favourites_comments': None, 'favourites_posts': None, 'friends': 3, 'notes': 0, 'posts': 1, 'publications': 8697, } assert profile.full is False assert profile.contacts is None assert profile.context['http_host'] == 'https://tabun.everypony.ru' assert profile.context['url'] == 'https://tabun.everypony.ru/profile/test/created/topics/' assert profile.context['can_vote'] is False # А здесь я прописал vote-nobuttons assert profile.context['vote_value'] is None assert profile.context['username'] == 'test' assert profile.context['note'] == '< > & " \'\ntest' assert profile.context['can_edit_note'] is True
def test_edit_comment_error(form_intercept, set_mock, user): set_mock({'/ajax/comment/edit/': ( None, {'data': '{"newText": "тест", "notice": null, "sMsgTitle": "Ошибка доступа", "sMsg": "Вы не можете изменять чужой комментарий, срок редактирования которого истёк", "bStateError": true}'.encode('utf-8')}, )}) @form_intercept('/ajax/comment/edit/') def edit_comment(data, headers): assert headers.get('content-type', '').startswith(b'multipart/form-data; boundary=-') assert data.get('security_ls_key') == [b'0123456789abcdef0123456789abcdef'] assert data.get('idComment') == [b'777'] assert data.get('newText') == ['тест2'.encode('utf-8')] assert data.get('setLock') == [b'0'] with pytest.raises(api.TabunResultError) as excinfo: user.edit_comment(777, 'тест2') assert excinfo.value.message == 'Вы не можете изменять чужой комментарий, срок редактирования которого истёк' assert excinfo.value.data.get('newText') == 'тест'
def test_cloudflare_solution_ok(set_mock, as_guest, intercept): cfdata = _get_cf_data() set_mock({ '/': cfdata['cf_mock'], '/login/': cfdata['cf_mock'], cfdata['answer_url']: cfdata['cf_mock_solved'], }) # Проверка того, что реализация не делает ничего лишнего calls = {'page': 0, 'solve': 0} @intercept('/') @intercept('/login/') def get_page(data, headers): calls['page'] += 1 @intercept(cfdata['answer_url']) def cf_solve(data, headers): calls['solve'] += 1 set_mock({ '/': 'index.html', '/login/': 'login.html', }) user = UserTest(avoid_cf=True) # Пытаемся открыть Табун, потом спим 4 секунды, решаем задачку CF и снова пытаемся assert calls == {'page': 2, 'solve': 1} assert user.sleeps == [1, 4.0] assert user.extra_cookies == { '__cfduid': cfdata['cookvalue1'], 'cf_clearance': cfdata['cookvalue2'], } assert user.session_id == 'abcdef9876543210abcdef9876543210' assert user.security_ls_key == '0123456789abcdef0123456789abcdef'
def test_add_comment_fail(set_mock, user): err = "Текст комментария должен быть от 2 до 3000 символов и не содержать разного рода каку" set_mock({'/blog/ajaxaddcomment/': (None, {'data': ('{"sMsgTitle": "Ошибка", "sMsg": "%s", "bStateError": true}' % err).encode('utf-8')})}) with pytest.raises(api.TabunResultError) as excinfo: user.comment(1, '') assert excinfo.value.message == err
def test_login_hacking_attemp(set_mock, user): set_mock({'/login/ajax-login': (None, {'data': b'Hacking attemp!'})}) with pytest.raises(api.TabunResultError) as excinfo: user.login('test', '123456') assert excinfo.value.message == 'Hacking attemp!'
def cf_solve(data, headers): calls['solve'] += 1 set_mock({ '/': 'index.html', '/login/': 'login.html', })
def test_ajax_hacking_attemp(set_mock, user): set_mock({'/ajax/': (None, {'data': b'Hacking attemp!'})}) with pytest.raises(api.TabunResultError) as excinfo: user.ajax('/ajax/', {'a': 5}) assert excinfo.value.message == 'Hacking attemp!'
def test_login_init_fail(set_mock, as_guest): set_mock({'/login/ajax-login': '******'}) with pytest.raises(api.TabunResultError): UserTest('test', '123456')
def test_login_init_ok(set_mock, as_guest): set_mock({'/login/ajax-login': '******'}) user = UserTest('test', '123456') testutil.guest_mode = False assert user.update_userinfo(user.urlopen('/').read()) == 'test' assert user.username == 'test'
def test_add_poll_error(set_mock, user): set_mock({'/question/add/': 'topic_add_error.html'}) with pytest.raises(api.TabunResultError) as excinfo: user.add_poll(None, '', ('foo', 'bar'), '', []) # TODO: test len(choices) > 20 assert excinfo.value.message == 'Поле Заголовок слишком короткое (минимально допустимо 2 символов)'
def test_get_post_other_blog_2(set_mock, user): set_mock({'/blog/blog/132085.html': ('132085.html', {'url': '/blog/132085.html'})}) assert user.get_post(132085, 'blog').blog is None
def test_add_post_error(set_mock, user): set_mock({'/topic/add/': 'topic_add_error.html'}) with pytest.raises(api.TabunResultError) as excinfo: user.add_post(None, '', '', []) assert excinfo.value.message == 'Поле Заголовок слишком короткое (минимально допустимо 2 символов)'