from ploneintranet.network.graph import NetworkGraph
from ploneintranet.network.interfaces import INetworkGraph
from ploneintranet.network.testing import IntegrationTestCase
from zope.interface.verify import verifyClass


class TestWatching(IntegrationTestCase):
    def test_verify_interface(self):
        self.assertTrue(verifyClass(INetworkGraph, NetworkGraph))

    def test_user_watch(self):
        g = NetworkGraph()
        g.watch("workspace", "feature-foo", "alex")  # alex watches feature-foo
        self.assertListEqual(["feature-foo"], list(g.get_watching("workspace", "alex")))

    def test_user_watch_watching(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard", "alex")
        g.watch("workspace", "caroline", "alex")
        g.watch("workspace", "dick", "alex")
        self.assertEqual(
            ["bernard", "caroline", "dick"],
            sorted(list(g.get_watching("workspace", "alex"))),
        )

    def test_user_watch_unwatch_watching(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard", "alex")
        g.watch("workspace", "caroline", "alex")
        g.unwatch("workspace", "bernard", "alex")
        self.assertEqual(["caroline"], list(g.get_watching("workspace", "alex")))

    def test_user_watch_watchers(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard", "alex")
        g.watch("workspace", "bernard", "caroline")
        self.assertEqual(
            ["alex", "caroline"], sorted(list(g.get_watchers("workspace", "bernard")))
        )

    def test_user_watch_unwatch_watchers(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard", "alex")
        g.watch("workspace", "bernard", "caroline")
        g.unwatch("workspace", "bernard", "alex")
        self.assertEqual(
            ["caroline"], sorted(list(g.get_watchers("workspace", "bernard")))
        )

    def test_user_is_watched(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard", "alex")
        self.assertTrue(g.is_watched("workspace", "bernard", "alex"))
        self.assertFalse(g.is_watched("workspace", "alex", "bernard"))
        self.assertFalse(g.is_watched("workspace", "caroline", "alex"))

    def test_keytypes_args(self):
        """BTree keys MUST be str instances. Check that the implementation
        enforces this."""
        g = NetworkGraph()
        self.assertRaises(AttributeError, g.watch, "workspace", 1, "2")
        self.assertRaises(AttributeError, g.watch, "workspace", "1", 2)
        self.assertRaises(AttributeError, g.unwatch, "workspace", 1, "2")
        self.assertRaises(AttributeError, g.unwatch, "workspace", "1", 2)
        self.assertRaises(AttributeError, g.get_watching, "workspace", 2)
        self.assertRaises(AttributeError, g.get_watchers, "workspace", 2)


class TestWatchingDefaults(IntegrationTestCase):
    """Check fallbacks to currently logged in user."""

    def test_user_watch_unwatch(self):
        g = NetworkGraph()
        g.watch("workspace", "bernard ☀")
        self.assertTrue(g.is_watching("workspace", "bernard ☀"))
        self.assertIn("bernard ☀", g.get_watching("workspace"))
        g.unwatch("workspace", "bernard ☀")
        self.assertFalse(g.is_watching("workspace", "bernard ☀"))
        self.assertNotIn("bernard ☀", g.get_watching("workspace"))
