def test_handleCreateAccount_DoubledTransaction(self):

        accountRepository = InMemoryRepository()
        transactionRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        accountRepository.add(Account(True, 75))
        transactionRepository.add(
            Transaction(
                "Burger King", 10,
                datetime.strptime("2019-02-13T11:00:00.000Z",
                                  '%Y-%m-%dT%H:%M:%S.%fZ')))
        transactionRepository.add(
            Transaction(
                "Burger King", 10,
                datetime.strptime("2019-02-13T11:01:59.000Z",
                                  '%Y-%m-%dT%H:%M:%S.%fZ')))

        command = AuthorizeTransaction(
            '{ "transaction": { "merchant": "Burger King", "amount": 10, "time": "2019-02-13T11:02:00.000Z" } }'
        )

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 75
            },
            "violations": ['doubled-transaction']
        }

        result = commandHandler.handle_AuthorizeTransaction(command)

        self.assertEqual(expectedResult, result)
    def test_handleCreateAccount_ok(self):

        repository = InMemoryRepository()
        commandHandler = AccountCommandHandler(repository)
        command = CreateAccount(
            '{ "account": { "activeCard": true, "availableLimit": 100 } }')

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 100
            },
            "violations": []
        }
        expectedAccount = {
            "account": {
                "activeCard": True,
                "availableLimit": 100
            }
        }

        result = commandHandler.handle_CreateAccount(command)

        self.assertEqual(expectedResult, result)

        resultAccount = repository.getByFilter(lambda _: True)[0].toDict()
        self.assertDictEqual(resultAccount, expectedAccount)
Esempio n. 3
0
def main():
    # Operates each line from STDIN. Supposing the program is called as following:
    # python ./src/application/app.py < operations

    # Repository Setup
    accountRepository = InMemoryRepository()
    transactionRepository = InMemoryRepository()

    # Command Bus Setup
    commandBus = InMemoryCommandBus()

    accountCommandsHandler = AccountCommandHandler(accountRepository)
    commandBus.subscribe(accountCommandsHandler)

    transactionCommandsHandler = TransactionCommandHandler(
        transactionRepository, accountRepository)
    commandBus.subscribe(transactionCommandsHandler)

    # Main loop
    for line in sys.stdin:
        command = getCommandFromJson(line)

        result = commandBus.send(command)
        output = json.dumps(result)

        print(output)
    def test_TransactionCommandHandlerCtor_ok(self):
        transactionRepository = InMemoryRepository()
        accountRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        self.assertEqual(transactionRepository,
                         commandHandler.transactionRepository)
        self.assertEqual(accountRepository, commandHandler.accountRepository)
        self.assertEqual(['AuthorizeTransaction'],
                         commandHandler.commandHandlerFuncNames)
    def test_RepoGetByFilter_NotFound(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                super().__init__()

        model = TestModel()

        repo.add(model)

        result = repo.getByFilter(lambda x: False)

        self.assertListEqual([], result)
    def test_RepoGetById_ok(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                super().__init__()

        model = TestModel()

        repo.add(model)

        result = repo.getById(model.id)

        self.assertEqual(model, result)
    def test_RepoGetByFilter_ok(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                super().__init__()

        model = TestModel()

        repo.add(model)

        result = repo.getByFilter(lambda x: x.id == model.id)

        self.assertListEqual([model], result)
    def test_RepoGetById_NotFound(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                super().__init__()

        model = TestModel()

        repo.add(model)

        result = repo.getById(uuid.uuid4())

        self.assertIsNone(result)
    def test_RepoAdd_ok(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                super().__init__()

        model = TestModel()

        rowsAffected = repo.add(model)

        self.assertIsNotNone(model.id)
        self.assertIsNotNone(model.created_at)
        self.assertEqual(1, len(repo.dbSet))
        self.assertEqual(1, rowsAffected)
    def test_handleCreateAccount_CommandNotAnInstance(self):

        accountRepository = InMemoryRepository()
        transactionRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        command = object()

        def handleAuthorizeTransactionFunc():
            commandHandler.handle_AuthorizeTransaction(command)

        self.assertRaisesWithMessage(
            AssertionError,
            '{} must be of type \'AuthorizeTransaction\''.format(command),
            handleAuthorizeTransactionFunc)
    def test_handleCreateAccount_InsufficientLimit(self):

        accountRepository = InMemoryRepository()
        transactionRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        accountRepository.add(Account(True, 100))

        command = AuthorizeTransaction(
            '{ "transaction": { "merchant": "Burger King", "amount": 101, "time": "2019-02-13T10:00:00.000Z" } }'
        )

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 100
            },
            "violations": ['insufficient-limit']
        }

        result = commandHandler.handle_AuthorizeTransaction(command)

        self.assertEqual(expectedResult, result)

        transactions = transactionRepository.getByFilter(lambda _: True)
        self.assertListEqual([], transactions)
    def test_AccountCommandHandlerCtor_ok(self):

        repository = InMemoryRepository()

        commandHandler = AccountCommandHandler(repository)

        self.assertEqual(repository, commandHandler.accountRepository)
        self.assertEqual(['CreateAccount'],
                         commandHandler.commandHandlerFuncNames)
    def test_TransactionCommandHandlerCtor_transactionRepo_nok(self):
        transactionRepository = object()
        accountRepository = InMemoryRepository()

        def createAccountCommandHandler():
            TransactionCommandHandler(transactionRepository, accountRepository)

        self.assertRaisesWithMessage(
            AssertionError,
            '{} must be of type \'Repository\''.format(transactionRepository),
            createAccountCommandHandler)
    def test_handleCreateAccount_ok(self):

        accountRepository = InMemoryRepository()
        transactionRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        accountRepository.add(Account(True, 100))

        command = AuthorizeTransaction(
            '{ "transaction": { "merchant": "Burger King", "amount": 10, "time": "2019-02-13T10:00:00.000Z" } }'
        )

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 90
            },
            "violations": []
        }
        expectedAccount = {
            "account": {
                "activeCard": True,
                "availableLimit": 90
            }
        }

        result = commandHandler.handle_AuthorizeTransaction(command)

        self.assertEqual(expectedResult, result)

        resultAccount = accountRepository.getByFilter(
            lambda _: True)[0].toDict()
        self.assertDictEqual(resultAccount, expectedAccount)
    def test_handleCreateAccount_NotAnInstance(self):

        repository = InMemoryRepository()
        commandHandler = AccountCommandHandler(repository)
        command = object()

        def handleCreateAccountFunc():
            commandHandler.handle_CreateAccount(command)

        self.assertRaisesWithMessage(
            AssertionError,
            '{} must be of type \'CreateAccount\''.format(command),
            handleCreateAccountFunc)
    def test_RepoAdd_NotModelInstance(self):
        repo = InMemoryRepository()

        model = object()

        def tryAddingNotModelInstance():
            repo.add(model)

        self.assertRaisesWithMessage(
            AssertionError,
            '{} entity must be of type \'Model\''.format(model),
            tryAddingNotModelInstance
        )
    def test_handleCreateAccount_AlreadyInitialized(self):

        repository = InMemoryRepository()
        repository.add(Account(True, 42))
        commandHandler = AccountCommandHandler(repository)
        command = CreateAccount(
            '{ "account": { "activeCard": true, "availableLimit": 100 } }')

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 42
            },
            "violations": ["account-already-initialized"]
        }

        result = commandHandler.handle_CreateAccount(command)

        self.assertDictEqual(expectedResult, result)

        emptyResults = repository.getByFilter(
            lambda account: account.availableLimit == 100)
        self.assertListEqual([], emptyResults)
    def test_RepoUpdate_NotFound(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                self.verified = False
                super().__init__()

        model = TestModel()

        repo.add(model)
        self.assertIsNone(model.updated_at)
        self.assertFalse(model.verified)

        newModel = Model()
        affectedRows = repo.update(newModel)
        self.assertEqual(0, affectedRows)

        notUpdatedModel = repo.getById(model.id)
        self.assertIsNone(notUpdatedModel.updated_at)
        self.assertFalse(notUpdatedModel.verified)
    def test_RepoUpdate_ok(self):
        repo = InMemoryRepository()

        class TestModel(Model):
            def __init__(self):
                self.verified = False
                super().__init__()

        model = TestModel()

        repo.add(model)
        self.assertIsNone(model.updated_at)
        self.assertFalse(model.verified)

        model.verified = True
        affectedRows = repo.update(model)
        self.assertEqual(1, affectedRows)

        updatedModel = repo.getById(model.id)
        self.assertIsNotNone(updatedModel.updated_at)
        self.assertTrue(updatedModel.verified)
    def test_RepoCtor_ok(self):
        repo = InMemoryRepository()

        self.assertDictEqual({}, repo.dbSet)
    def test_handleCreateAccount_HighFrequencySmallInterval(self):

        accountRepository = InMemoryRepository()
        transactionRepository = InMemoryRepository()

        commandHandler = TransactionCommandHandler(transactionRepository,
                                                   accountRepository)

        accountRepository.add(Account(True, 75))
        transactionRepository.add(
            Transaction(
                "Burger King", 10,
                datetime.strptime("2019-02-13T11:00:00.000Z",
                                  '%Y-%m-%dT%H:%M:%S.%fZ')))
        transactionRepository.add(
            Transaction(
                "Burger Queen", 10,
                datetime.strptime("2019-02-13T11:01:00.000Z",
                                  '%Y-%m-%dT%H:%M:%S.%fZ')))
        transactionRepository.add(
            Transaction(
                "Burger Prince", 5,
                datetime.strptime("2019-02-13T11:01:59.000Z",
                                  '%Y-%m-%dT%H:%M:%S.%fZ')))

        command = AuthorizeTransaction(
            '{ "transaction": { "merchant": "Burger Pleb", "amount": 10, "time": "2019-02-13T10:00:00.000Z" } }'
        )

        expectedResult = {
            "account": {
                "activeCard": True,
                "availableLimit": 75
            },
            "violations": ['high-frequency-small-interval']
        }

        result = commandHandler.handle_AuthorizeTransaction(command)

        self.assertEqual(expectedResult, result)