Example #1
0
    def test_should_skip_invalid_xml_files(self, mock_open, mock_logger):

        mock_open.side_effect = [self.valid_xml_file, self.invalid_xml_file]

        model = Model(['/path/to/file1', '/path/to/file2'])

        self.assertEqual(1, len(model.banks))
        self.assertEqual(1, len(model.debtors))
        self.assertEqual(1, len(model.replies))

        bank = model.banks.pop()

        self.assertEqual('12345678', bank.code)
        self.assertEqual('12345678', bank.name)

        debtor = model.debtors.pop()

        self.assertEqual('Jan Kowalski', debtor.name)
        self.assertEqual('PESEL', debtor.identity.name)
        self.assertEqual('12345678900', debtor.identity.value)

        reply = model.replies[debtor][bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(2016, 12, 31, 0, 0), reply.date)
        self.assertTrue(reply.has_account)
        self.assertEqual('/path/to/file1', reply.file_path)

        mock_logger.assert_has_calls([
            mock.call.debug('Processed file %d of %d "%s"', 1, 2,
                            '/path/to/file1'),
            mock.call.error('Invalid or not well-formed XML content at %s',
                            '/path/to/file2')
        ])
Example #2
0
    def test_should_ignore_duplicates_within_single_file(self):

        self.mock_parser.entities = mock.PropertyMock(return_value=5 *
                                                      [self.JAN_KOWALSKI])

        model = Model(['/path/to/file'])

        self.assertEqual(1, len(model.replies.keys()))

        debtor = list(model.replies.keys()).pop()

        self.assertEqual('Jan Kowalski', debtor.name)
        self.assertEqual('PESEL', debtor.identity.name)
        self.assertEqual('12345678900', debtor.identity.value)

        banks_replies_for_debtor = model.replies[debtor]

        self.assertEqual(1, len(banks_replies_for_debtor.keys()))

        bank = list(banks_replies_for_debtor.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file', reply.file_path)
Example #3
0
    def test_should_have_many_banks_with_many_debtors(self):

        self.mock_parser.entities = [self.JAN_KOWALSKI, self.ANNA_NOWAK]

        model = Model(self.files.keys())

        self.assertEqual(2, len(model.banks))
        self.assertEqual(2, len(model.debtors))
Example #4
0
    def test_should_have_one_bank_with_many_debtors(self):

        self.mock_parser.entities = [self.JAN_KOWALSKI, self.ANNA_NOWAK]

        model = Model(['/path/to/file'])

        self.assertEqual(1, len(model.banks))
        self.assertEqual(2, len(model.debtors))
Example #5
0
    def test_should_have_many_banks_without_debtors(self):

        self.mock_parser.entities = []

        model = Model(self.files.keys())

        self.assertEqual(2, len(model.banks))
        self.assertEqual(0, len(model.debtors))
Example #6
0
    def test_should_have_one_bank_without_debtors(self):

        self.mock_parser.entities = []

        model = Model(['/path/to/file'])

        self.assertEqual(1, len(model.banks))
        self.assertEqual(0, len(model.debtors))
Example #7
0
    def test_should_have_no_banks_nor_debtors(self):

        self.mock_parser.entities = []

        model = Model([])

        self.assertEqual(0, len(model.banks))
        self.assertEqual(0, len(model.debtors))
Example #8
0
    def test_should_return_empty_dict_if_no_legal_entities_parsed(self):

        self.mock_parser.entities = []

        model = Model(self.files.keys())

        self.assertIsInstance(model.replies, collections.defaultdict)
        self.assertDictEqual({}, model.replies)

        self.assertEqual(2, len(model.banks))
        self.assertEqual(0, len(model.debtors))
Example #9
0
    def test_should_have_banks(self):

        model = Model(self.files.keys())

        bank1, bank2 = sorted(model.banks, key=lambda x: x.code)

        self.assertEqual('00123', bank1.code)
        self.assertEqual('Lorem Bank', bank1.name)

        self.assertEqual('30211', bank2.code)
        self.assertEqual('Dolor Bank', bank2.name)
Example #10
0
    def test_collation_should_accept_str(self):

        self.mock_parser.entities = [self.JAN_KOWALSKI, self.ANNA_NOWAK]

        model = Model(['/path/to/file'])

        debtor1, debtor2 = model.sorted_debtors

        self.assertEqual('Jan Kowalski', debtor1.name)
        self.assertEqual('PESEL', debtor1.identity.name)
        self.assertEqual('12345678900', debtor1.identity.value)

        self.assertEqual('Anna Nowak', debtor2.name)
        self.assertEqual('PESEL', debtor2.identity.name)
        self.assertEqual('98765432100', debtor2.identity.value)
Example #11
0
    def test_should_have_debtors(self):

        self.mock_parser.entities = [self.JAN_KOWALSKI, self.FIRMA_1]

        model = Model(self.files.keys())

        debtor1, debtor2 = sorted(model.debtors, key=lambda x: x.name)

        self.assertEqual('Firma Sp. z O.O.', debtor1.name)
        self.assertEqual('NIP', debtor1.identity.name)
        self.assertEqual('1234567890', debtor1.identity.value)

        self.assertEqual('Jan Kowalski', debtor2.name)
        self.assertEqual('PESEL', debtor2.identity.name)
        self.assertEqual('12345678900', debtor2.identity.value)
Example #12
0
def main(args):
    """Application entry point."""
    try:
        init_config(args.config)
        init_logging(args.debug)

        logger.debug(str(config()))

        if os.path.exists(args.output) and not args.force_overwrite:
            logger.error(
                'File already exists. Use the -f flag to force overwrite.')
        else:
            model = Model(get_file_paths())
            report = Report(model)

            if report.save(args.output):
                webbrowser.open(args.output)

    except KeyboardInterrupt:
        logger.info('Aborted with ^C')
Example #13
0
    def test_legal_entity_with_multiple_bank_accounts(self):

        self.mock_parser.entities = mock.PropertyMock(
            side_effect=[[self.JAN_KOWALSKI_2], [self.JAN_KOWALSKI_2]])

        model = Model(self.files.keys())

        self.assertEqual(1, len(model.replies.keys()))

        debtor = list(model.replies.keys()).pop()

        self.assertEqual('jan kowalski', debtor.name.lower())
        self.assertEqual('PESEL', debtor.identity.name)
        self.assertEqual('12345678900', debtor.identity.value)

        banks_replies_for_debtor = model.replies[debtor]

        self.assertEqual(2, len(banks_replies_for_debtor.keys()))

        bank1, bank2 = sorted(banks_replies_for_debtor.keys(),
                              key=lambda x: x.code)

        self.assertEqual('00123', bank1.code)
        self.assertEqual('Lorem Bank', bank1.name)

        self.assertEqual('30211', bank2.code)
        self.assertEqual('Dolor Bank', bank2.name)

        reply1 = banks_replies_for_debtor[bank1]

        self.assertEqual(bank1, reply1.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply1.date)
        self.assertTrue(reply1.has_account)
        self.assertEqual('/path/to/file1', reply1.file_path)

        reply2 = banks_replies_for_debtor[bank2]

        self.assertEqual(bank2, reply2.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply2.date)
        self.assertTrue(reply2.has_account)
        self.assertEqual('/path/to/file2', reply2.file_path)
Example #14
0
    def test_should_ignore_and_warn_about_contradicting_replies_in_single_file(
            self, mock_logger):

        self.mock_parser.entities = mock.PropertyMock(
            side_effect=[[self.JAN_KOWALSKI, self.JAN_KOWALSKI_2]])

        model = Model(['/path/to/file'])

        self.assertEqual(1, len(model.replies.keys()))

        debtor = list(model.replies.keys()).pop()

        self.assertEqual('jan kowalski', debtor.name.lower())
        self.assertEqual('PESEL', debtor.identity.name)
        self.assertEqual('12345678900', debtor.identity.value)

        self.assertEqual(0, len(model.replies[debtor]))

        mock_logger.warning.assert_called_once_with(
            'Inconsistent replies from the same bank %s for %s', mock.ANY,
            debtor)
Example #15
0
    def test_should_warn_about_and_resolve_contradicting_replies_by_date(
            self, mock_logger):

        self.mock_parser.bank_code = '00123'
        self.mock_parser.date = mock.PropertyMock(side_effect=[
            dateutil.parser.parse('1970-01-01'),
            dateutil.parser.parse('1990-12-31')
        ])
        self.mock_parser.entities = mock.PropertyMock(
            side_effect=[[self.JAN_KOWALSKI], [self.JAN_KOWALSKI_2]])

        model = Model(self.files.keys())

        self.assertEqual(1, len(model.replies.keys()))

        debtor = list(model.replies.keys()).pop()

        self.assertEqual('jan kowalski', debtor.name.lower())
        self.assertEqual('PESEL', debtor.identity.name)
        self.assertEqual('12345678900', debtor.identity.value)

        banks_replies_for_debtor = model.replies[debtor]

        self.assertEqual(1, len(banks_replies_for_debtor.keys()))

        bank = list(banks_replies_for_debtor.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1990, 12, 31, 0, 0), reply.date)
        self.assertTrue(reply.has_account)
        self.assertEqual('/path/to/file2', reply.file_path)

        mock_logger.warning.assert_called_once_with(
            'Inconsistent replies from the same bank %s for %s', mock.ANY,
            debtor)
Example #16
0
    def test_should_sort_debtors_by_name_using_unicode_collation(self):

        it = itertools.count(1)

        def identity():
            return Id('PESEL', next(it))

        def person(first_name, last_name):
            return NaturalPerson(first_name, last_name, identity(), False)

        def legal(name):
            return LegalEntity(name, identity(), False)

        self.mock_parser.entities = [
            person('Karol', 'Walczak'),
            person('Maja', 'Szulc'),
            person('Franciszek', 'Ostrowski'),
            person('Leon', 'Mucha'),
            legal('Auchan'),
            person('Wiktoria', 'Pawlak'),
            person('Natalia', 'Kasprzak'),
            person('Hanna', 'Majchrzak'),
            person('Kacper', 'Krupa'),
            person('Tymon', 'Dąbrowski'),
            legal('Carrefour'),
            person('Julian', 'Sowa'),
            person('Mikołaj', 'Ostrowski'),
            person('Zuzanna', 'Kozioł'),
            person('Anna', 'Augustyniak'),
            person('Weronika', 'Markowska'),
            legal('Biedronka'),
            person('Wiktoria', 'Rogowska'),
            person('Łukasz', 'Łuczak'),
            person('Maksymilian', 'Górski'),
            legal('Tesco'),
            person('Alicja', 'Morawska'),
            legal('Żabka'),
            person('Szymon', 'Kosiński'),
            person('Piotr', 'Tomczyk'),
            person('Kacper', 'Olejnik'),
            person('Szymon', 'Wójcik'),
            person('Miłosz', 'Zalewski'),
            person('Karolina', 'Lewandowska'),
            person('Urszula', 'Lewandowska'),
            person('Tymoteusz', 'Kowalik'),
            person('Sebastian', 'Krupa'),
            person('Urszula', 'Kaźmierczak'),
            person('Kacper', 'Barański'),
            person('Szymon', 'Sobolewski'),
            person('Filip', 'Nawrocki'),
            legal('Lewiatan'),
            person('Anna', 'Kołodziej'),
            person('Jan', 'Król'),
            person('Julia', 'Markiewicz'),
            person('Lena', 'Karpińska'),
            person('Wiktoria', 'Marzec'),
            person('Olaf', 'Matusiak'),
            person('Dominika', 'Nowak'),
            person('Stanisław', 'Kurek')
        ]

        model = Model(['/path/to/file'])

        self.assertListEqual([
            'Auchan', 'Biedronka', 'Carrefour', 'Lewiatan', 'Tesco', 'Żabka',
            'Anna Augustyniak', 'Kacper Barański', 'Tymon Dąbrowski',
            'Maksymilian Górski', 'Lena Karpińska', 'Natalia Kasprzak',
            'Urszula Kaźmierczak', 'Anna Kołodziej', 'Szymon Kosiński',
            'Tymoteusz Kowalik', 'Zuzanna Kozioł', 'Jan Król', 'Kacper Krupa',
            'Sebastian Krupa', 'Stanisław Kurek', 'Karolina Lewandowska',
            'Urszula Lewandowska', 'Łukasz Łuczak', 'Hanna Majchrzak',
            'Julia Markiewicz', 'Weronika Markowska', 'Wiktoria Marzec',
            'Olaf Matusiak', 'Alicja Morawska', 'Leon Mucha', 'Filip Nawrocki',
            'Dominika Nowak', 'Kacper Olejnik', 'Franciszek Ostrowski',
            'Mikołaj Ostrowski', 'Wiktoria Pawlak', 'Wiktoria Rogowska',
            'Szymon Sobolewski', 'Julian Sowa', 'Maja Szulc', 'Piotr Tomczyk',
            'Karol Walczak', 'Szymon Wójcik', 'Miłosz Zalewski'
        ], [x.name for x in model.sorted_debtors])
Example #17
0
    def test_multiple_legal_entities_single_reply(self):

        self.mock_parser.entities = mock.PropertyMock(
            return_value=[self.JAN_KOWALSKI, self.ANNA_NOWAK, self.FIRMA_1])

        model = Model(['/path/to/file'])

        self.assertEqual(3, len(model.replies.keys()))

        debtor1, debtor2, debtor3 = sorted(model.replies.keys(),
                                           key=lambda x: x.name)

        self.assertEqual('Anna Nowak', debtor1.name)
        self.assertEqual('PESEL', debtor1.identity.name)
        self.assertEqual('98765432100', debtor1.identity.value)

        self.assertEqual('Firma Sp. z O.O.', debtor2.name)
        self.assertEqual('NIP', debtor2.identity.name)
        self.assertEqual('1234567890', debtor2.identity.value)

        self.assertEqual('Jan Kowalski', debtor3.name)
        self.assertEqual('PESEL', debtor3.identity.name)
        self.assertEqual('12345678900', debtor3.identity.value)

        banks_replies_for_debtor1 = model.replies[debtor1]

        self.assertEqual(1, len(banks_replies_for_debtor1.keys()))

        bank = list(banks_replies_for_debtor1.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor1[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertTrue(reply.has_account)
        self.assertEqual('/path/to/file', reply.file_path)

        banks_replies_for_debtor2 = model.replies[debtor2]

        self.assertEqual(1, len(banks_replies_for_debtor2.keys()))

        bank = list(banks_replies_for_debtor2.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor2[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file', reply.file_path)

        banks_replies_for_debtor3 = model.replies[debtor3]

        self.assertEqual(1, len(banks_replies_for_debtor3.keys()))

        bank = list(banks_replies_for_debtor3.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor3[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file', reply.file_path)
Example #18
0
    def test_multiple_legal_entities_multiple_replies(self):

        self.mock_parser.entities = mock.PropertyMock(
            side_effect=[[self.JAN_KOWALSKI, self.FIRMA_1],
                         [self.JAN_KOWALSKI, self.FIRMA_2, self.ANNA_NOWAK]])

        model = Model(self.files.keys())

        self.assertEqual(4, len(model.replies.keys()))

        debtor1, debtor2, debtor3, debtor4 = sorted(model.replies.keys(),
                                                    key=lambda x: x.name)

        self.assertEqual('Amber Scam Sp. z O.O.', debtor1.name)
        self.assertEqual('REGON', debtor1.identity.name)
        self.assertEqual('123456789', debtor1.identity.value)

        self.assertEqual('Anna Nowak', debtor2.name)
        self.assertEqual('PESEL', debtor2.identity.name)
        self.assertEqual('98765432100', debtor2.identity.value)

        self.assertEqual('Firma Sp. z O.O.', debtor3.name)
        self.assertEqual('NIP', debtor3.identity.name)
        self.assertEqual('1234567890', debtor3.identity.value)

        self.assertEqual('Jan Kowalski', debtor4.name)
        self.assertEqual('PESEL', debtor4.identity.name)
        self.assertEqual('12345678900', debtor4.identity.value)

        banks_replies_for_debtor1 = model.replies[debtor1]

        self.assertEqual(1, len(banks_replies_for_debtor1.keys()))

        bank = list(banks_replies_for_debtor1.keys()).pop()

        self.assertEqual('30211', bank.code)
        self.assertEqual('Dolor Bank', bank.name)

        reply = banks_replies_for_debtor1[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertTrue(reply.has_account)
        self.assertEqual('/path/to/file2', reply.file_path)

        banks_replies_for_debtor2 = model.replies[debtor2]

        self.assertEqual(1, len(banks_replies_for_debtor2.keys()))

        bank = list(banks_replies_for_debtor2.keys()).pop()

        self.assertEqual('30211', bank.code)
        self.assertEqual('Dolor Bank', bank.name)

        reply = banks_replies_for_debtor2[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertTrue(reply.has_account)
        self.assertEqual('/path/to/file2', reply.file_path)

        banks_replies_for_debtor3 = model.replies[debtor3]

        self.assertEqual(1, len(banks_replies_for_debtor3.keys()))

        bank = list(banks_replies_for_debtor3.keys()).pop()

        self.assertEqual('00123', bank.code)
        self.assertEqual('Lorem Bank', bank.name)

        reply = banks_replies_for_debtor3[bank]

        self.assertEqual(bank, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file1', reply.file_path)

        banks_replies_for_debtor4 = model.replies[debtor4]

        self.assertEqual(2, len(banks_replies_for_debtor4.keys()))

        bank1, bank2 = sorted(banks_replies_for_debtor4.keys(),
                              key=lambda x: x.code)

        self.assertEqual('00123', bank1.code)
        self.assertEqual('Lorem Bank', bank1.name)

        reply = banks_replies_for_debtor4[bank1]

        self.assertEqual(bank1, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file1', reply.file_path)

        self.assertEqual('00123', bank1.code)
        self.assertEqual('Lorem Bank', bank1.name)

        reply = banks_replies_for_debtor4[bank2]

        self.assertEqual(bank2, reply.bank)
        self.assertEqual(datetime.datetime(1970, 1, 1, 0, 0), reply.date)
        self.assertFalse(reply.has_account)
        self.assertEqual('/path/to/file2', reply.file_path)