def wrapper(*args, **kwargs): has_error = kwargs.get('has_error') response = func(*args, **kwargs) r = response.json() logging.debug('response: %s', pp.pformat(r)) if 'error' not in r: return logging.warning('Facebook send api error: %s', pp.pformat(r)) user_status = args[0] user = user_status.user # 2018065: over 24hours # 2018108 ,1545041: User blocked or left and we can't send message. if r['error'].get('error_subcode') in (2018108, 1545041, 2018065): MatchingQueue.remove(user) if user.partner: pc = UserContext(user.partner) pc.send_btn( pc._("Stranger has disconnected."), [pc.new_chat(), pc.langb()], action.TALKING__ERROR_AND_DISCONNECTED) user.partner.partner = None user_status.delegate.on_match_ended(user_status, pc) # don't send message if this is called by error elif not has_error: user_status.send_message( user_status._('Sending failed. Try it again later.'), action.FB_ERROR_RETURNED, has_error=True)
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 _do_search(self, message): if not self.delegate.on_try_search(self): return partner = MatchingQueue.match_partner(self.user) if partner: self.match_user(partner, message) return MatchingQueue.push(self.user) self.send_message(self._( "Finding someone you can chat with..." ), action.IDLE__ACTION_SEARCH_WAITING)
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_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_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 match_user(self, partner, message): logging.debug('match user %s and %s', self.user.id, partner.id) session = Session() try: pc = UserContext(partner) self.user.partner = partner partner.partner = self.user self.user.last_matched = partner.id partner.last_matched = self.user.id record = MatchingQueue.remove(partner) # パートナーと関連が可能かを確認するためにコミットする session.commit() self.delegate.on_found_partner(self, pc, record) title = "You're now chatting with someone new!\n" subtitle = "Choose 'Menu' from the menu '≡'" \ " in the corner or tap the button bellow" \ " to terminate your conversation." def send_matched(userc1, userc2, event): if userc1.user.version >= "2.0" and userc2.user.version >= "2.0": return userc1.send_action(fb.generic_template_itsb( userc1.user.id, userc1._(title), userc1._(subtitle), fb.profile_picture(userc2.user.fb_id), [b(userc1._("End Chat"), END_CONVERSATION), b(userc1._("Share Your Profile"), SHARE_PROFILE_PRE)]), event) else: return userc1.send_action( fb.generic_template_b( userc1.user.id, userc1._(title), userc1._(subtitle), [ b(userc1._("End Chat"), END_CONVERSATION), b(userc1._("Share Your Profile"), SHARE_PROFILE_PRE)]), event) send_matched(pc, self, action.IDLE__ACTION_SEARCH_FOUND_PASSIVE) # if partner block us, we handle error occured above and user.partner is deleted. if self.user.partner: send_matched(self, pc, action.IDLE__ACTION_SEARCH_FOUND) else: self.do_search(message) except IntegrityError as e: session.rollback() logging.exception(e) self.do_search(message)
def cancel_search(self, message): MatchingQueue.remove(self.user) self.send_btn( self._("Searching interrupted."), [self.langb(), self.new_chat()], action.SEARCHING__ACTION_CANCEL)
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