def __init__(self, conversation_id, default_response): self.cid = conversation_id # self.domain = "https://riobot.centralus.cloudapp.azure.com" self.domain = "https://antislapp.ca" self.default = default_response self.defence = Defence(index.db, self.cid) self.response = { 'speech': default_response, 'displayText': default_response, # 'event': {"name":"<event_name>","data":{"<parameter_name>":"<parameter_value>"}}, # 'data': _, # 'contextOut': [{"name":"weather", "lifespan":2, "parameters":{"city":"Rome"}}], # context name must be lowercase 'source': 'riobot', } self.defence_triggers = { 'plead': 'trigger-plead', 'question': 'trigger-bool', 'facts': 'trigger-facts', 'Truth': 'trigger-truth', 'Absolute Privilege': 'trigger-absolute', 'Qualified Privilege': 'trigger-qualified', 'Fair Comment': 'trigger-fair', 'Responsible Communication': 'trigger-responsible', 'check-antislapp': 'trigger-antislapp', 'check-defamatory': 'trigger-defamatory', 'check-damaging': 'trigger-damaging', 'check-apology': 'trigger-apology', 'check-court': 'trigger-court', 'exit-deny': 'trigger-exit-deny', }
def test_plead(): d1 = Defence(db, 'convo1') d1.reset() d1.save() with pytest.raises(IndexError): d1.plead(0, "agree") acc1 = d1.add_allegation("acc1", 4) with pytest.raises(ValueError): d1.plead(acc1, "dook") acc2 = d1.add_allegation('acc2', 5) acc3 = d1.add_allegation('acc3', 6) d1.plead(acc1, "agree") d1.plead(acc2, "deny") d1.plead(acc3, "withhold") accs = d1.get_claims() assert accs == [ {'allegation': 'acc1', 'paragraph': 4, 'plead': 'agree'}, {'allegation': 'acc2', 'paragraph': 5, 'plead': 'deny'}, {'allegation': 'acc3', 'paragraph': 6, 'plead': 'withhold'}, ]
def test_save(): d1 = Defence(db, 'convo1') d2 = Defence(db, 'convo2') d1.reset() d1.save() d2.reset() d2.save() d1.add_allegation('libel', 4) d2.add_allegation('slander', 5) d1acc = [acc['allegation'] for acc in d1.get_claims()] d2acc = [acc['allegation'] for acc in d2.get_claims()] assert d1acc == ['libel'] assert d2acc == ['slander'] d1b = Defence(db, 'convo1') d2b = Defence(db, 'convo2') assert d1b.get_claims() == [] assert d2b.get_claims() == [] d1.save() d2.save() d1c = Defence(db, 'convo1') d2c = Defence(db, 'convo2') d1cacc = [acc['allegation'] for acc in d1c.get_claims()] d2cacc = [acc['allegation'] for acc in d2c.get_claims()] assert d1cacc == ['libel'] assert d2cacc == ['slander']
def test_accusations(): d1 = Defence(db, 'convo1') d1.reset() d1.save() d1acc = [acc['allegation'] for acc in d1.get_claims()] assert d1acc == [] d1.add_allegation('acc1', 4) d1acc = [acc['allegation'] for acc in d1.get_claims()] assert d1acc == ['acc1'] d1.add_allegation('acc2', 5) d1acc = [acc['allegation'] for acc in d1.get_claims()] assert d1acc == ['acc1', 'acc2'] d1.add_allegation('acc3', 6) d1acc = [acc['allegation'] for acc in d1.get_claims()] assert d1acc == ['acc1', 'acc2', 'acc3'] d1b = Defence(db, 'convo1') assert d1b.get_claims() == [] d1.save() d1c = Defence(db, 'convo1') d1cacc = [acc['allegation'] for acc in d1c.get_claims()] assert d1cacc == ['acc1', 'acc2', 'acc3']
def test_sued(): d1 = Defence(db, 'convo1') d1.reset() d1.save() assert d1.report() == "In summary, you may have been sued." d1.set_sued(True) assert d1.report() == "In summary, you have been sued." d1.set_sued(False) assert d1.report() == "In summary, you have not been sued."
def test_report(): d1 = Defence(db, 'convo1') d1.reset() d1.save() acw = d1.add_allegation('accW', 4) aca = d1.add_allegation('accA', 5) ac1 = d1.add_allegation('acc1', 6) ac2 = d1.add_allegation('acc2', 7) d1.plead(acw, 'withhold') d1.plead(aca, 'agree') d1.plead(ac1, 'deny') d1.plead(ac2, 'deny') d1.add_defence(ac1, 'Truth', True) d1.add_defence(ac1, 'Absolute Privilege', False) d1.add_defence(ac1, 'Qualified Privilege', True) d1.add_defence(ac2, 'Fair Comment', True) report = d1.report() assert report == 'In summary, you may have been sued. You agree with the claims in paragraphs 5. You deny the ' \ 'allegations in paragraphs 6 and 7. You cannot respond to claims in paragraphs 4.' d2 = Defence(db, 'convo2') d2.reset() d2.save() d2.set_sued(True) report = d2.report() assert report == "In summary, you have been sued." d2.set_sued(False) report = d2.report() assert report == "In summary, you have not been sued."
def test_resp_comm(): resp_comm = ResponsibleDefence({}) d1 = Defence(db, 'convo1') d1.reset() d1.save() ac1 = d1.add_allegation('issue A', 4) d1.plead(ac1, 'deny') d1.add_defence(ac1, 'Truth', False) d1.add_defence(ac1, 'Absolute Privilege', False) d1.add_defence(ac1, 'Qualified Privilege', False) d1.add_defence(ac1, 'Fair Comment', False) d1.add_defence(ac1, 'Responsible Communication', True) expected = { 'claim_id': ac1, 'allegation': 'issue A', 'defence': 'Responsible Communication', 'next_step': 'question', 'data': {'question': resp_comm.extra_questions[0]}, } assert d1.get_next_step() == expected d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[0], 'answer': True}) d1.save() d1 = Defence(db, 'convo1') expected['data']['question'] = resp_comm.extra_questions[1] assert d1.get_next_step() == expected d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[1], 'answer': False}) d1.save() d1 = Defence(db, 'convo1') expected['data']['question'] = resp_comm.extra_questions[2] assert d1.get_next_step() == expected d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[2], 'answer': True}) d1.save() d1 = Defence(db, 'convo1') expected['data']['question'] = resp_comm.extra_questions[3] assert d1.get_next_step() == expected d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[3], 'answer': 'skip'}) d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[4], 'answer': True}) d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[5], 'answer': 'skip'}) d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[6], 'answer': False}) d1.save() d1 = Defence(db, 'convo1') expected = { 'claim_id': ac1, 'allegation': 'issue A', 'defence': 'Responsible Communication', 'next_step': 'facts', 'data': {}, } assert d1.get_next_step() == expected rc = d1.get_defence(ac1, 'Responsible Communication') assert rc.applicable == True d1.update_defence(ac1, 'Responsible Communication', {'question': resp_comm.extra_questions[3], 'answer': False}) assert rc.applicable == False
def test_determine_next_defence(): d1 = Defence(db, 'convo1') d1.reset() d1.save() assert d1.get_next_step() is None acw = d1.add_allegation('accW', 4) aca = d1.add_allegation('accA', 5) ac1 = d1.add_allegation('acc1', 6) ac2 = d1.add_allegation('acc2', 7) assert d1.get_next_step() == {'claim_id': acw, 'allegation': 'accW', 'next_step': 'plead'} d1.plead(acw, 'withhold') assert d1.get_next_step() == {'claim_id': aca, 'allegation': 'accA', 'next_step': 'plead'} d1.plead(aca, 'agree') assert d1.get_next_step() == {'claim_id': ac1, 'allegation': 'acc1', 'next_step': 'plead'} d1.plead(ac1, 'deny') d1.plead(ac2, 'deny') assert d1.get_next_step() == {'claim_id': ac1, 'allegation': 'acc1', 'defence': 'Truth', 'next_step': 'Truth'} d1.add_defence(ac1, 'Truth', False) assert d1.get_next_step() == {'claim_id': ac1, 'allegation': 'acc1', 'defence': 'Absolute Privilege', 'next_step': 'Absolute Privilege'} d1.add_defence(ac1, 'Absolute Privilege', True) assert d1.get_next_step() == {'claim_id': ac1, 'allegation': 'acc1', 'defence': 'Absolute Privilege', 'next_step': 'facts', 'data': {}} d1.done_facts(ac1, 'Absolute Privilege') d1.add_defence(ac1, 'Qualified Privilege', True) d1.done_facts(ac1, 'Qualified Privilege') d1.add_defence(ac1, 'Fair Comment', False) assert d1.get_next_step() == {'claim_id': ac1, 'allegation': 'acc1', 'defence': 'Responsible Communication', 'next_step': 'Responsible Communication'} d1.add_defence(ac1, 'Responsible Communication', False) assert d1.get_next_step() == {'claim_id': ac2, 'allegation': 'acc2', 'defence': 'Truth', 'next_step': 'Truth'} d1.add_defence(ac2, 'Truth', True) assert d1.get_next_step() == {'claim_id': ac2, 'allegation': 'acc2', 'defence': 'Truth', 'next_step': 'facts', 'data': {}} d1.done_facts(ac2, 'Truth') assert d1.get_next_step() == {'claim_id': ac2, 'allegation': 'acc2', 'defence': 'Absolute Privilege', 'next_step': 'Absolute Privilege'} d1.add_defence(ac2, 'Absolute Privilege', False) d1.add_defence(ac2, 'Qualified Privilege', False) d1.add_defence(ac2, 'Fair Comment', False) d1.add_defence(ac2, 'Responsible Communication', False) assert d1.get_next_step() is None
def test_get_pleads(): d1 = Defence(db, 'convo1') d1.reset() d1.save() acc1 = d1.add_allegation("acc1", 4) acc2 = d1.add_allegation("acc2", 5) acc3 = d1.add_allegation("acc3", 6) acc4 = d1.add_allegation("acc4", 7) d1.plead(acc1, 'agree') d1.plead(acc2, 'deny') d1.plead(acc3, 'withhold') ags = d1.get_agreed() dns = d1.get_denied() whs = d1.get_withheld() assert len(ags) == 1 assert len(dns) == 1 assert len(whs) == 2 assert ags[0]['allegation'] == 'acc1' assert dns[0]['allegation'] == 'acc2' assert whs[0]['allegation'] == 'acc3' assert whs[1]['allegation'] == 'acc4' d1.plead(acc1, 'withhold') d1.plead(acc2, 'withhold') assert d1.get_agreed() == [] assert d1.get_denied() == [] d1.plead(acc1, 'deny') d1.plead(acc2, 'deny') d1.plead(acc3, 'deny') d1.plead(acc4, 'deny') assert d1.get_withheld() == []
def test_facts(): d1 = Defence(db, 'convo1') d1.reset() d1.save() acc1 = d1.add_allegation("acc1", 4) d1.add_defence(acc1, 'Truth', True) d1.add_defence(acc1, 'Fair Comment', True) with pytest.raises(IndexError): d1.add_fact(1000, 'Truth', 'he said she said') with pytest.raises(ValueError): d1.add_fact(acc1, 'AboveTheLaw', 'she said he said') d1.add_fact(acc1, 'Truth', 'exhibit A') d1.add_fact(acc1, 'Truth', 'exhibit B') d1.add_fact(acc1, 'Truth', 'exhibit C') a = d1.get_claims() d = a[0]['Truth'] assert d.applicable is True assert d.facts == ['exhibit A', 'exhibit B', 'exhibit C']
def test_defence(): d1 = Defence(db, 'convo1') d1.reset() d1.save() acc1 = d1.add_allegation("acc1", 4) with pytest.raises(IndexError): d1.add_defence(1000, 'Truth', True) with pytest.raises(ValueError): d1.add_defence(acc1, 'AboveTheLaw', True) d1.add_defence(acc1, 'Truth', 'true') a = d1.get_claims() assert 'Truth' in a[0] assert a[0]['Truth'].applicable is True d1.add_defence(acc1, 'Truth', 'false') a = d1.get_claims() assert 'Truth' in a[0] assert a[0]['Truth'].applicable is True d1.add_defence(acc1, 'Truth', False) a = d1.get_claims() assert 'Truth' in a[0] assert a[0]['Truth'].applicable is False d1.add_defence(acc1, 'Absolute Privilege', False) d1.add_defence(acc1, 'Qualified Privilege', False) d1.add_defence(acc1, 'Fair Comment', False) d1.add_defence(acc1, 'Responsible Communication', False) a = d1.get_claims() assert 'Truth' in a[0] assert 'Absolute Privilege' in a[0] assert 'Qualified Privilege' in a[0] assert 'Fair Comment' in a[0] assert 'Responsible Communication' in a[0]
class Controller: def __init__(self, conversation_id, default_response): self.cid = conversation_id # self.domain = "https://riobot.centralus.cloudapp.azure.com" self.domain = "https://antislapp.ca" self.default = default_response self.defence = Defence(index.db, self.cid) self.response = { 'speech': default_response, 'displayText': default_response, # 'event': {"name":"<event_name>","data":{"<parameter_name>":"<parameter_value>"}}, # 'data': _, # 'contextOut': [{"name":"weather", "lifespan":2, "parameters":{"city":"Rome"}}], # context name must be lowercase 'source': 'riobot', } self.defence_triggers = { 'plead': 'trigger-plead', 'question': 'trigger-bool', 'facts': 'trigger-facts', 'Truth': 'trigger-truth', 'Absolute Privilege': 'trigger-absolute', 'Qualified Privilege': 'trigger-qualified', 'Fair Comment': 'trigger-fair', 'Responsible Communication': 'trigger-responsible', 'check-antislapp': 'trigger-antislapp', 'check-defamatory': 'trigger-defamatory', 'check-damaging': 'trigger-damaging', 'check-apology': 'trigger-apology', 'check-court': 'trigger-court', 'exit-deny': 'trigger-exit-deny', } def set_sued(self, sued, plaintiff): self.defence.set_sued(sued) if plaintiff is not None: self.defence.set_plaintiff(plaintiff) def set_defendant(self, name): self.defence.set_defendant(name) def add_allegation(self, allegation, paragraph): return self.defence.add_allegation(allegation, paragraph) def get_definition(self, term): dfn = definitions.get(term.lower(), "That term isn't in the dictionary") self.response['speech'] = dfn self.response['displayText'] = dfn def set_next_step(self): next_step = self.defence.get_next_step() # next_question has .claim_id, .acc, .qst OR is None if next_step is None: self.response['followupEvent'] = { 'name': 'trigger-summary', 'data': { 'preface': ' ' } } else: data = next_step.pop('data', {}) if 'preface' not in data: data['preface'] = ' ' step = next_step.pop('next_step', 'report') self.response['contextOut'] = [{ 'name': 'currentacc', 'lifespan': 20, 'parameters': next_step }] self.response['followupEvent'] = { 'name': self.defence_triggers[step], 'data': data } self.response.pop('speech', None) # required to be absent self.response.pop('displayText', None) # required to be absent def make_plea(self, context, params): cid = int(float(context['parameters']['claim_id'])) # plead may be one of Defence.PLEADS ('agree', 'withhold', 'deny') self.defence.plead(cid, params['plead']) self.set_next_step() def defence_check(self, context, params): defence = context['parameters']['defence'] self.defence.add_defence(defence, params['applicable']) self.set_next_step() def add_fact(self, context, fact): defence = context['parameters']['defence'] self.defence.add_fact(defence, fact) def done_facts(self, context): defence = context['parameters']['defence'] self.defence.done_facts(defence) self.set_next_step() def set_damaging(self, damaging): self.defence.set_damaging(damaging) self.set_next_step() def set_defamatory(self, defamatory): self.defence.set_defamatory(defamatory) self.set_next_step() def set_apology(self, params): self.defence.set_apology(params['happened'], params['date'], params['method']) self.set_next_step() def set_antislapp(self, ontario, public): self.defence.set_antislapp(ontario and public) self.set_next_step() def set_court_name(self, court_name): self.defence.set_court_name(court_name) self.set_next_step() def boolean_answer(self, context, answer): defence = context['parameters']['defence'] info = { 'question': context['parameters']['question'], 'answer': answer } self.defence.update_defence(defence, info) self.set_next_step() def get_missing_numbers(self, found_numbers): numbers = [] for fnum in found_numbers: if type(fnum) in (float, int): numbers.append(int(fnum)) continue numstrings = fnum.split(",") for numstring in numstrings: if numstring.strip().isdigit(): numbers.append(int(numstring)) continue # ranges of form 1..3 or 1-3 with spaces anywhere match = re.match(r'\s*(\d+)\s*(?:-+|\.\.+)\s*(\d+)\s*', numstring) if match: a = int(match.group(1)) b = int(match.group(2)) numbers.extend(range(min(a, b), max(a, b) + 1)) highest = max(numbers) missing = [] for i in range(1, highest): if i not in numbers: missing.append(i) groups = self.group_ranges(missing) return groups def group_ranges(self, numbers): # turns lists like [3,2,7,6,8] and [1,2,3,4,6,7,9,10] # into lists like ['2-3', '6-8'] and ['1-4', '6-7', '9-10'] if len(numbers) == 0: return [] nums = sorted(list(set(numbers))) grouped_missing = [] prev = nums[0] run = 0 for n in nums[1:]: if n == prev + 1: run += 1 else: if run == 0: grouped_missing.append("{}".format(prev)) else: grouped_missing.append("{}-{}".format(prev - run, prev)) run = 0 prev = n if run == 0: grouped_missing.append("{}".format(prev)) else: grouped_missing.append("{}-{}".format(prev - run, prev)) return grouped_missing def report(self): report = self.defence.report() # if any paragraphs are missing from the pleadings, mention them here missing_paragraphs = self.get_missing_numbers( [claim['paragraph'] for claim in self.defence.get_claims()]) if missing_paragraphs: report += "\n\nSome paragraph numbers ({}) of allegations made seem to be missing. It is important that " \ "all allegation paragraphs are accounted for in paragraphs 1, 2, or 3 of Part 1 Division 1 in " \ "your defence below.".format(index.join_list(missing_paragraphs)) # If antislapp legislation applies, mention that! if self.defence.get_antislapp() is True: report += "\n\nSince you're being sued in Ontario, and it's about a matter of public interest, you can " \ "request the court dismiss the proceeding in accordance with the Protection of Public " \ "Participation Act (PPPA). This would be ideal, and a legal professional will be able to " \ "help you." # fill out the statement of defence form = FormS2600(self.cid) if self.defence.get_defendant() is not None: form.defendant = self.defence.get_defendant() if self.defence.get_plaintiff() is not None: form.plaintiff = self.defence.get_plaintiff() if self.defence.get_court_name() is not None: form.court_name = self.defence.get_court_name() form.claims_unanswered = self.defence.get_withheld() form.claims_denied = self.defence.get_denied() form.claims_admitted = self.defence.get_agreed() if 'apology' in self.defence.data and self.defence.data['apology'][ 'applicable'] is True: form.apology_given = True form.apology_date = self.defence.data['apology']['date'] form.apology_method = self.defence.data['apology']['method'] else: form.apology_given = False form.was_damaging = self.defence.data.get('is_damaging', None) form.was_defamatory = self.defence.data.get('is_defamatory', None) defences = self.defence.get_defences() defence_paragraphs = [] fact_paragraphs = [] for defence in Defence.DEFENCES: if defence in defences and defences[defence].applicable is True: defence_paragraphs.append(defences[defence].report()) fact_paragraphs.extend(defences[defence].facts) form.set_defences(defence_paragraphs) form.set_additional_facts(fact_paragraphs) form.write() report = report + "\n\nDownload your Statement of Defence " \ "[{}{}](here).".format(self.domain, form.get_link()) # steps steps = SuitSteps(self.cid) steps.populate(self.defence) steps.write() report = report + "\n\nDownload your Defence Guide " \ "[{}{}](here).".format(self.domain, steps.get_link()) # advice for next steps offer_advice = False if offer_advice: lawyer_name = "XYZ incorporated" lawyer_site = "https://example.com" report += "\n\nThe above documents are as far as I can take you. For additional support, I would recommend connecting with a legal representative from [{site}]({name}). Good luck to you!".format( name=lawyer_name, site=lawyer_site) self.response['speech'] = report self.response['displayText'] = report def reset(self): self.defence.reset() def save(self): self.defence.save() def get_response(self): return self.response