# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from unittest import TestCase
from mock import patch
from sqlalchemy.orm import sessionmaker
from sqlalchemy.engine import Engine
from edbob.configuration import AppConfigParser
from rattail import db
from rattail.db.util import configure_session_factory
class TestConfigureSessionFactory(TestCase):
def setUp(self):
self.config = AppConfigParser(u'rattail')
self.config.add_section(u'rattail.db')
self.Session = sessionmaker()
def test_session_is_not_bound_if_no_engine_is_defined_by_config(self):
configure_session_factory(self.config, session_factory=self.Session)
session = self.Session()
self.assertTrue(session.bind is None)
session.close()
def test_session_is_correctly_bound_if_engine_is_defined_by_config(self):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite:////a/very/custom/db')
session = self.Session()
self.assertTrue(session.bind is None)
session.close()
configure_session_factory(self.config, session_factory=self.Session)
session = self.Session()
self.assertTrue(isinstance(session.bind, Engine))
self.assertEqual(unicode(session.bind.url), u'sqlite:////a/very/custom/db')
session.close()
def test_global_session_is_configured_by_default(self):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite:////path/to/rattail.sqlite')
session = db.Session()
self.assertTrue(session.bind is None)
session.close()
configure_session_factory(self.config)
session = db.Session()
self.assertTrue(isinstance(session.bind, Engine))
self.assertEqual(unicode(session.bind.url), u'sqlite:////path/to/rattail.sqlite')
session.close()
# Must undo that configuration, this thing is global.
db.Session.configure(bind=None)
@patch(u'rattail.db.changes.record_changes')
def test_changes_will_not_be_recorded_by_default(self, record_changes):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite://')
configure_session_factory(self.config, session_factory=self.Session)
self.assertFalse(record_changes.called)
@patch('rattail.db.util.record_changes')
def test_changes_will_be_recorded_by_so_configured(self, record_changes):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite://')
self.config.set(u'rattail.db', u'changes.record', u'true')
configure_session_factory(self.config, session_factory=self.Session)
# Role changes are ignored by default.
record_changes.assert_called_once_with(self.Session, True)
@patch('rattail.db.util.record_changes')
def test_changes_will_still_be_recorded_with_deprecated_config(self, record_changes):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite://')
self.config.set(u'rattail.db', u'changes.record', u'true')
configure_session_factory(self.config, session_factory=self.Session)
# Role changes are ignored by default.
record_changes.assert_called_once_with(self.Session, True)
@patch('rattail.db.util.record_changes')
def test_config_determines_if_role_changes_are_ignored(self, record_changes):
self.config.set(u'rattail.db', u'sqlalchemy.url', u'sqlite://')
self.config.set(u'rattail.db', u'changes.record', u'true')
self.config.set(u'rattail.db', u'changes.ignore_roles', u'false')
configure_session_factory(self.config, session_factory=self.Session)
# Role changes are ignored by default; False means config works.
record_changes.assert_called_once_with(self.Session, False)