import influxframework
from influxframework.tests.utils import InfluxFrameworkTestCase
from influxframework.utils.safe_exec import get_safe_globals, safe_exec


class TestSafeExec(InfluxFrameworkTestCase):
	def test_import_fails(self):
		self.assertRaises(ImportError, safe_exec, "import os")

	def test_internal_attributes(self):
		self.assertRaises(SyntaxError, safe_exec, "().__class__.__call__")

	def test_utils(self):
		_locals = dict(out=None)
		safe_exec("""out = influxframework.utils.cint("1")""", None, _locals)
		self.assertEqual(_locals["out"], 1)

	def test_safe_eval(self):
		self.assertEqual(influxframework.safe_eval("1+1"), 2)
		self.assertRaises(AttributeError, influxframework.safe_eval, "influxframework.utils.os.path", get_safe_globals())

	def test_sql(self):
		_locals = dict(out=None)
		safe_exec(
			"""out = influxframework.db.sql("select name from tabDocType where name='DocType'")""", None, _locals
		)
		self.assertEqual(_locals["out"][0][0], "DocType")

		self.assertRaises(
			influxframework.PermissionError, safe_exec, 'influxframework.db.sql("update tabToDo set description=NULL")'
		)

	def test_query_builder(self):
		_locals = dict(out=None)
		safe_exec(
			script="""out = influxframework.qb.from_("User").select(influxframework.qb.terms.PseudoColumn("Max(name)")).run()""",
			_globals=None,
			_locals=_locals,
		)
		self.assertEqual(influxframework.db.sql("SELECT Max(name) FROM tabUser"), _locals["out"])

	def test_safe_query_builder(self):
		self.assertRaises(
			influxframework.PermissionError, safe_exec, """influxframework.qb.from_("User").delete().run()"""
		)

	def test_call(self):
		# call non whitelisted method
		self.assertRaises(influxframework.PermissionError, safe_exec, """influxframework.call("influxframework.get_user")""")

		# call whitelisted method
		safe_exec("""influxframework.call("ping")""")

	def test_enqueue(self):
		# enqueue non whitelisted method
		self.assertRaises(
			influxframework.PermissionError, safe_exec, """influxframework.enqueue("influxframework.get_user", now=True)"""
		)

		# enqueue whitelisted method
		safe_exec("""influxframework.enqueue("ping", now=True)""")
