def test_match_last_matched(mocker, monkeypatch): fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, ) from chatty.domain.model.match import Language, MatchingQueue import requests mock_request(monkeypatch, requests) session = Session() english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) user = User('TEST-01') user.languages = [english] partner = User('TEST-02') partner.languages = [english] session.add(user) session.add(partner) session.commit() MatchingQueue.push(partner) assert MatchingQueue.match_partner(user) == partner MatchingQueue.remove(partner) user.partner = None user.last_matched = partner.id MatchingQueue.push(partner) assert MatchingQueue.match_partner(user) == None user.last_matched = "other" assert MatchingQueue.match_partner(user) == partner
def test_on_match_end(mocker, monkeypatch): fix_matcher_rand(mocker) delegate = UserStateDelegate() user = User.create("test1", finding_genders="female", gender="male", points=30) partner = User.create("test2", finding_genders="female,male", gender="female", points=30) time = datetime.datetime.utcnow() record = MatchingQueue(created_at=time, finding_genders="male,female") uc, pc = [UserContext(u) for u in [user, partner]] delegate.on_found_partner(uc, pc, record) delegate.on_speak(uc) delegate.on_speak(uc) delegate.on_speak(pc) delegate.on_match_ended(uc, pc) assert Match.get("test1") is None assert Match.get("test2") is None res = MatchHistory.get("test1") assert len(res) == 1 assert res[0].founder_id == "test1" assert res[0].waiter_id == "test2" assert res[0].founder_speech_count == 2 assert res[0].waiter_speech_count == 1 assert res[0].founder_used_points == 10 assert res[0].waiter_used_points == 0 assert res[0].waited_at == time assert res[0].ended_by == "test1" assert res[0].started_at > time
def test_user_default_languages(mocker, monkeypatch, caplog): fix_matcher_rand(mocker) from chatty.domain.model.match import (User, Language) # session session = Session() english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) ar = (session.query(Language).get('ar_AR') or Language(id='ar_AR', name='Arabic')) user = User('TEST-01') assert set(user.languages) == set([english]) monkeypatch.setattr(User, 'locale', 'xx_XX') user = User('TEST-02') assert set(user.languages) == set([english]) monkeypatch.setattr(User, 'locale', 'ar_AR') user = User('TEST-03') assert set(user.languages) == set([ar])
def test_on_match_increment_speech(mocker, monkeypatch): fix_matcher_rand(mocker) delegate = UserStateDelegate() user = User.get("test1") partner = User.get("test2") time = datetime.datetime.utcnow() record = MatchingQueue(created_at=time, finding_genders="male,female") uc, pc = [UserContext(u) for u in [user, partner]] delegate.on_found_partner(uc, pc, record) m1 = Match.get("test1") assert m1.founder_speech_count == 0 assert m1.waiter_speech_count == 0 delegate.on_speak(uc) assert m1.founder_speech_count == 1 assert m1.waiter_speech_count == 0 delegate.on_speak(uc) assert m1.founder_speech_count == 2 assert m1.waiter_speech_count == 0 delegate.on_speak(pc) assert m1.founder_speech_count == 2 assert m1.waiter_speech_count == 1 delegate.on_speak(pc) assert m1.founder_speech_count == 2 assert m1.waiter_speech_count == 2
def test_on_try_search_on_banned(mocker, monkeypatch): fix_matcher_rand(mocker) delegate = UserStateDelegate() uc = UserContext(User.create("test1", "male,female", "male", 30)) us = uc.status from chatty.util import fb mocksend = MagicMock() monkeypatch.setattr(fb, "send_data", mocksend) black_list.ban_user("test1") assert not delegate.on_try_search(us) assert mocksend.call_count == 1 assert_message_is(mocksend.call_args_list[0][0][0], "test1", "suspended")
def test_match_location(mocker, monkeypatch): fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, ) from chatty.domain.model.match import Language import requests mock_request(monkeypatch, requests) session = Session() english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) user1 = User('TEST-01') user1.languages = [english] user2 = User('TEST-02') user2.languages = [english] session.add(user1) session.add(user2) session.commit() cache = dict(my_langs=set([english])) mat = matcher.get() # default, both don't use location assert mat.should_match(user1, user2, cache, True) user1.location_enabled = True # user1 wanna use location but don't have, so ignore. # user2 doesn't care location. match. assert mat.should_match(user1, user2, cache, True) # at TokyoTocho user1.current_longitude = 139.4130 user1.current_latitude = 35.4122 assert not mat.should_match(user1, user2, cache, True) assert mat.should_match(user1, user2, cache, False) # at OsakaShiyakusho user2.current_longitude = 135.3008 user2.current_latitude = 34.4138 # user2 is in user1 radius 400, and user2 doesn't care radius assert mat.should_match(user1, user2, cache, True) user2.location_enabled = True assert mat.should_match(user1, user2, cache, True) user2.search_radius = 100 assert not mat.should_match(user1, user2, cache, True) assert mat.should_match(user1, user2, cache, False) user1.current_longitude = 136.3008 user1.current_latitude = 34.4138 assert mat.should_match(user1, user2, cache, True)
def test_match_gender(mocker, monkeypatch): fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, ) from chatty.domain.model.match import Language, MatchingQueue import requests mock_request(monkeypatch, requests) session = Session() english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) user = User('TEST-01') user.languages = [english] user.gender = "male" partner = User('TEST-02') partner.languages = [english] partner.gender = "female" partner.finding_genders = "male,female" user.finding_genders = "female" session.add(user) session.add(partner) session.commit() MatchingQueue.push(partner) assert MatchingQueue.match_partner(user) == partner MatchingQueue.remove(partner) user.partner = None MatchingQueue.push(partner) user.finding_genders = "male" assert MatchingQueue.match_partner(user) == None user.finding_genders = "male,female" assert MatchingQueue.match_partner(user) == partner user.partner = None MatchingQueue.remove(partner) MatchingQueue.push(partner) partner.finding_genders = "female" assert MatchingQueue.match_partner(user) == None user.gender = "undefined" assert MatchingQueue.match_partner(user) == None
def test_user_location(mocker, monkeypatch): fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, ) import requests mock_request(monkeypatch, requests) user1 = User('TEST-01') assert user1.has_location() == False # at TokyoTocho user1.current_longitude = 139.4130 assert user1.has_location() == False user1.current_latitude = 35.4122 assert user1.has_location() == True user2 = User('TEST-02') # at OsakaShiyakusho user2.current_longitude = 135.3008 user2.current_latitude = 34.4138 # about 400km distance between tokyo and osaka assert abs(user1.distance(user2) - 400) < 10
def test_on_found_partner(mocker, monkeypatch): delegate = UserStateDelegate() fix_matcher_rand(mocker) user = User.create("test1", finding_genders="male,female", gender="male", points=30) partner = User.create("test2", finding_genders="male,female", gender="male", points=30) uc, pc = [UserContext(u) for u in [user, partner]] record = MatchingQueue(created_at=datetime.datetime.utcnow(), finding_genders="male,female") delegate.on_found_partner(uc, pc, record) assert user.points == 30 assert partner.points == 30 assert Match.get("test1").founder_used_points == 0 delegate.on_match_ended(uc, pc) user.finding_genders = "female" partner.gender = "female" delegate.on_found_partner(uc, pc, record) assert user.points == 20 assert partner.points == 30 assert Match.get("test1").founder_used_points == 10 assert Match.get("test1").waiter_used_points == 0 delegate.on_match_ended(uc, pc) delegate.on_found_partner(pc, uc, record) assert user.points == 20 assert partner.points == 30 record.finding_genders = "female" delegate.on_match_ended(uc, pc) delegate.on_found_partner(pc, uc, record) assert user.points == 10 assert partner.points == 30 assert Match.get("test1").founder_used_points == 0 assert Match.get("test1").waiter_used_points == 10
def test_on_try_search(mocker, monkeypatch): fix_matcher_rand(mocker) delegate = UserStateDelegate() uc = UserContext(User.create("test1", "male,female", "male", 30)) us = uc.status from chatty.util import fb mocksend = MagicMock() monkeypatch.setattr(fb, "send_data", mocksend) assert delegate.on_try_search(us) assert mocksend.call_count == 0 us.user.points = 0 assert delegate.on_try_search(us) assert mocksend.call_count == 0 us.user.finding_genders = "female" assert not delegate.on_try_search(us) assert mocksend.call_count == 1 assert_button(mocksend.call_args_list[0][0][0], "test1", "enough points", [fb.web_button("", "/buy_points", "", "")])
def test_state_transition(mocker, monkeypatch): """状態遷移のテスト""" fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, IdleUserState, SearchingUserState, TalkingUserState, ) from chatty.domain.model.match import Language import requests mock_request(monkeypatch, requests) # session session = model.Session() # ユーザーの言語設定を行う english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) user1 = User('TEST-01') user1.languages = [english] user2 = User('TEST-02', 'TEST-02') user2.languages = [english] user3 = User('TEST-03', 'TEST-03') user3.languages = [english] session.add(user1) session.add(user2) session.commit() user1_c = UserContext(user1) user2_c = UserContext(user2) user3_c = UserContext(user3) # At first, must be NoSignUpIdle assert isinstance(user1_c.status, NoSignUpIdleUserState) user1.fb_id = "1234" assert isinstance(user1_c.status, IdleUserState) # ユーザをサーチ状態にする user1_c.do_search(None) session.commit() assert isinstance(user1_c.status, SearchingUserState) # ユーザーを会話状態にする user2_c.do_search(None) session.commit() assert isinstance(user1_c.status, TalkingUserState) assert isinstance(user2_c.status, TalkingUserState) # 会話を終了する user2_c.end_conversation_and_search(None) session.commit() assert isinstance(user1_c.status, IdleUserState) assert isinstance(user2_c.status, SearchingUserState) # not match same tuple user1_c.do_search(None) session.commit() assert isinstance(user1_c.status, SearchingUserState) assert isinstance(user2_c.status, SearchingUserState) # match with pother partners. user3_c.do_search(None) session.commit() assert isinstance(user1_c.status, SearchingUserState) assert isinstance(user2_c.status, TalkingUserState) assert isinstance(user3_c.status, TalkingUserState) # 会話を終了する user2_c.end_conversation(None) session.commit() assert isinstance(user1_c.status, SearchingUserState) assert isinstance(user2_c.status, IdleUserState) assert isinstance(user3_c.status, IdleUserState) user1_c.cancel_search(None) session.commit() assert isinstance(user1_c.status, IdleUserState)
def test_user_state_check_error(mocker, monkeypatch, caplog): fix_matcher_rand(mocker) from chatty.domain.user_state import ( User, IdleUserState, SearchingUserState, TalkingUserState, ) from chatty.domain.model.match import Language import requests from chatty.util.fb import requests as fbreq mock_request(monkeypatch, requests) mock_request(monkeypatch, fbreq) # session session = model.Session() # ユーザーの言語設定を行う english = (session.query(Language).get('en_US') or Language(id='en_US', name='English')) user = User('TEST-01', 'TEST-01') user.languages = [english] partner = User('TEST-02', 'TEST-02') partner.languages = [english] session.add(user) session.add(partner) session.commit() user_c = UserContext(user) partner_c = UserContext(partner) # logging 設定 caplog.set_level(logging.INFO) # エラーが返ってきた場合ワーニングログを出力 mock_request(monkeypatch, fbreq, {"error": { "code": 190, "error_subcode": 1234567, }}) user_c.status.send_message('message', action.IDLE__MESSAGE) # warning log が出力されているはず for rec in caplog.records: print('log: ', rec) if (rec.levelname == 'WARNING' and rec.message.startswith('Facebook send api error:')): break else: assert False, 'Not found error message' session.commit() # メッセージ送信先がメッセージを受信できない場合は検索,会話状態から削除する # 検索状態へ normalres = { 'message_id': 'mid.1484759787552:e29cca0c16', 'recipient_id': '1261793003907488' } mock_request(monkeypatch, fbreq, normalres) user_c.do_search(None) session.commit() assert isinstance(user_c.status, SearchingUserState) mock_request( monkeypatch, fbreq, {"error": { "code": 10, "error_subcode": 2018108, }}, ) user_c.status.send_message('message', action.SEARCHING__MESSAGE) session.commit() # アイドル状態になっているはず assert isinstance(user_c.status, IdleUserState) # 会話状態へ mock_request(monkeypatch, fbreq, normalres) user_c.do_search(None) partner_c.do_search(None) session.commit() assert isinstance(user_c.status, TalkingUserState) assert isinstance(partner_c.status, TalkingUserState) def m(url, json): recipient_ = json['recipient']['id'] if recipient_ == "TEST-01": return MagicMock(json=MagicMock(return_value=normalres)) elif recipient_ == "TEST-02": return MagicMock(json=MagicMock( return_value={ "error": { "code": 200, "error_subcode": 1545041, } })) raise ValueError( "dummy recipient must be TEST-01 or TEST-02 but {}".format( recipient_)) monkeypatch.setattr(fbreq, 'post', m) user_c.status.do_message( MagicMock(message=MagicMock(text="hello", _fields=["text"]))) session.commit() # アイドル状態になっているはず assert isinstance(user_c.status, IdleUserState) assert isinstance(partner_c.status, IdleUserState)