class TestUIActionsRealFile(tests.TestCase):
    def setUp(self):
        window = EmptyWindowObject()
        self.notebook = self.setUpNotebook(mock=tests.MOCK_ALWAYS_REAL,
                                           content={'Test': 'Test 123'})
        self.page = self.notebook.get_page(Path('Test'))
        self.navigation = MockNavigation()
        self.uiactions = UIActions(
            window,
            self.notebook,
            self.page,
            self.navigation,
        )

    def testDeletePageWithTrash(self):
        self.assertTrue(self.page.exists())

        with tests.DialogContext():  # fails if dialog shown
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())

    def testDeletePageWithoutTrash(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        def do_delete(dialog):
            dialog.assert_response_ok()

        with tests.DialogContext(do_delete):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())

    def testDeletePageWithoutTrashAndChildren(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())
        child = self.notebook.get_page(Path('Test:Child'))
        child.parse('wiki', 'Test 123')
        self.notebook.store_page(child)
        dir = self.notebook.get_attachments_dir(self.page)
        self.assertTrue(dir.exists())
        dir.folder('foo').touch()

        def do_delete(dialog):
            dialog.assert_response_ok()

        with tests.DialogContext(do_delete):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertFalse(dir.exists())

    def testDeletePageWithoutTrashCancel(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        def do_delete(dialog):
            dialog.do_response_cancel()

        with tests.DialogContext(do_delete):
            self.uiactions.delete_page()

        self.assertTrue(self.page.exists())

    def testDeletePageWithTrashUpdateLinks(self):
        from zim.config import ConfigManager
        ConfigManager.preferences['GtkInterface'].input(
            remove_links_on_delete=True)
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext():  # fails if dialog shown
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test Test\n'])

    def testDeletePageWithTrashNoUpdateLinks(self):
        from zim.config import ConfigManager
        ConfigManager.preferences['GtkInterface'].input(
            remove_links_on_delete=False)
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext():  # fails if dialog shown
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testDeletePageWithoutTrashUpdateLinks(self):
        from zim.config import ConfigManager

        self.notebook.config['Notebook']['disable_trash'] = True
        ConfigManager.preferences['GtkInterface'].input(
            remove_links_on_delete=True)
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def do_delete(dialog):
            dialog.assert_response_ok()

        with tests.DialogContext(do_delete):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test Test\n'])

    def testDeletePageWithoutTrashNoUpdateLinks(self):
        from zim.config import ConfigManager

        self.notebook.config['Notebook']['disable_trash'] = True
        ConfigManager.preferences['GtkInterface'].input(
            remove_links_on_delete=False)
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        def do_delete(dialog):
            dialog.assert_response_ok()

        with tests.DialogContext(do_delete):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testOpenAttachmentsFolderExisting(self):
        folder = self.notebook.get_attachments_dir(self.page)
        folder.touch()

        def open_folder(cmd):
            self.assertEqual(cmd[-1], folder.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext():
                self.uiactions.open_attachments_folder()

    def testOpenAttachmentsFolderNonExisting(self):
        folder = self.notebook.get_attachments_dir(self.page)
        self.assertFalse(folder.exists())

        def create_folder(dialog):
            dialog.answer_yes()

        def open_folder(cmd):
            self.assertEqual(cmd[-1], folder.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext(create_folder):
                self.uiactions.open_attachments_folder()

    def testOpenNotebookFolder(self):
        def open_folder(cmd):
            self.assertEqual(cmd[-1], self.notebook.folder.path)

        with tests.ApplicationContext(open_folder):
            self.uiactions.open_notebook_folder()

    def testOpenDocumentRoot(self):
        from zim.gui.widgets import ErrorDialog
        self.notebook.document_root = self.setUpFolder(
            mock=tests.MOCK_ALWAYS_REAL)
        self.notebook.document_root.touch()

        def open_folder(cmd):
            self.assertEqual(cmd[-1], self.notebook.document_root.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext():
                self.uiactions.open_document_root()

    def testOpenDocumentRootNotDefined(self):
        from zim.gui.widgets import ErrorDialog

        self.assertIsNone(self.notebook.document_root)

        with tests.LoggingFilter('zim', 'No document root defined'):
            with tests.ApplicationContext():
                with tests.DialogContext(ErrorDialog):
                    self.uiactions.open_document_root()

    def testEditPageSource(self):
        from zim.gui.widgets import MessageDialog
        from zim.newfs import LocalFile
        from zim.gui.applications import ApplicationManager

        oldtext = self.page.dump('plain')  # trick page into caching content
        signals = tests.SignalLogger(self.page)

        def edit_page(cmd):
            file = LocalFile(cmd[-1])
            self.assertEqual(file, self.page.source_file)
            file.write('New text\n')

        manager = ApplicationManager()
        entry = manager.create('text/plain', 'test', 'test')
        manager.set_default_application('text/plain', entry)

        with tests.ApplicationContext(edit_page):
            with tests.DialogContext(MessageDialog):
                self.uiactions.edit_page_source()

        newtext = self.page.dump('plain')
        self.assertEqual(signals['storage-changed'],
                         [(True, )])  # boolean for external change
        self.assertNotEqual(oldtext, newtext)
class TestUIActionsRealFile(tests.TestCase):
    def setUp(self):
        window = EmptyWindowObject()
        self.notebook = self.setUpNotebook(mock=tests.MOCK_ALWAYS_REAL,
                                           content={'Test': 'Test 123'})
        self.page = self.notebook.get_page(Path('Test'))
        self.navigation = MockNavigation()
        self.uiactions = UIActions(
            window,
            self.notebook,
            self.page,
            self.navigation,
        )

    def testTrashPage(self):
        self.assertTrue(self.page.exists())

        with tests.DialogContext(TrashPageDialog):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())

    def testTrashPageCancel(self):
        self.assertTrue(self.page.exists())

        def cancel_delete(dialog):
            assert isinstance(dialog, TrashPageDialog)
            dialog.do_response_cancel()

        with tests.DialogContext(cancel_delete):
            self.uiactions.delete_page()

        self.assertTrue(self.page.exists())

    def testTrashPageFallbackToDelete(self):
        from zim.newfs.helpers import TrashNotSupportedError
        self.assertTrue(self.page.exists())

        def mock_trash_iter(*a, **k):
            yield
            raise TrashNotSupportedError('Test')

        self.notebook.trash_page_iter = mock_trash_iter

        def fail_trash(dialog):
            assert isinstance(dialog, TrashPageDialog)
            dialog.do_response_ok()  # NOT assert_repsonse_ok - we want to fail

        def question_yes(dialog):
            dialog.answer_yes()

        with tests.DialogContext(fail_trash, question_yes, DeletePageDialog):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())

    def testTrashPageFallbackToDeleteCancel(self):
        from zim.newfs.helpers import TrashNotSupportedError
        self.assertTrue(self.page.exists())

        def mock_trash_iter(*a, **k):
            yield
            raise TrashNotSupportedError('Test')

        self.notebook.trash_page_iter = mock_trash_iter

        def fail_trash(dialog):
            assert isinstance(dialog, TrashPageDialog)
            dialog.do_response_ok()  # NOT assert_repsonse_ok - we want to fail

        def question_no(dialog):
            dialog.answer_no()

        with tests.DialogContext(fail_trash, question_no):
            self.uiactions.delete_page()

        self.assertTrue(self.page.exists())

    def testDeletePage(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        with tests.DialogContext(DeletePageDialog):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())

    def testDeletePageAndChildren(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())
        child = self.notebook.get_page(Path('Test:Child'))
        child.parse('wiki', 'Test 123')
        self.notebook.store_page(child)
        dir = self.notebook.get_attachments_dir(self.page)
        self.assertTrue(dir.exists())
        dir.folder('foo').touch()

        with tests.DialogContext(DeletePageDialog):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertFalse(dir.exists())

    def testDeletePageCancel(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        def cancel_delete(dialog):
            assert isinstance(dialog, DeletePageDialog)
            dialog.do_response_cancel()

        with tests.DialogContext(cancel_delete):
            self.uiactions.delete_page()

        self.assertTrue(self.page.exists())

    def testTrashPageUpdateLinks(self):
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext(
            (TrashPageDialog,
             lambda d: d.update_links_checkbutton.set_active(True))):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test Test\n'])

    def testTrashPageNoUpdateLinks(self):
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext(
            (TrashPageDialog,
             lambda d: d.update_links_checkbutton.set_active(False))):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testDeletePageUpdateLinks(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext(
            (DeletePageDialog,
             lambda d: d.update_links_checkbutton.set_active(True))):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test Test\n'])

    def testDeletePageNoUpdateLinks(self):
        self.notebook.config['Notebook']['disable_trash'] = True
        self.assertTrue(self.page.exists())

        referrer = self.notebook.get_page(Path('Referrer'))
        referrer.parse('wiki', 'Test [[Test]]\n')
        self.notebook.store_page(referrer)

        with tests.DialogContext(
            (DeletePageDialog,
             lambda d: d.update_links_checkbutton.set_active(False))):
            self.uiactions.delete_page()

        self.assertFalse(self.page.exists())
        self.assertEqual(referrer.dump('wiki'), ['Test [[Test]]\n'])

    def testOpenAttachmentsFolderExisting(self):
        folder = self.notebook.get_attachments_dir(self.page)
        folder.touch()

        def open_folder(cmd):
            self.assertEqual(strip_file_url_prefix(cmd[-1]), folder.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext():
                self.uiactions.open_attachments_folder()

    def testOpenAttachmentsFolderNonExisting(self):
        folder = self.notebook.get_attachments_dir(self.page)
        self.assertFalse(folder.exists())

        def create_folder(dialog):
            dialog.answer_yes()

        def open_folder(cmd):
            self.assertEqual(strip_file_url_prefix(cmd[-1]), folder.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext(create_folder):
                self.uiactions.open_attachments_folder()

    def testOpenNotebookFolder(self):
        def open_folder(cmd):
            self.assertEqual(strip_file_url_prefix(cmd[-1]),
                             self.notebook.folder.path)

        with tests.ApplicationContext(open_folder):
            self.uiactions.open_notebook_folder()

    def testOpenDocumentRoot(self):
        from zim.gui.widgets import ErrorDialog
        self.notebook.document_root = self.setUpFolder(
            mock=tests.MOCK_ALWAYS_REAL)
        self.notebook.document_root.touch()

        def open_folder(cmd):
            self.assertEqual(strip_file_url_prefix(cmd[-1]),
                             self.notebook.document_root.path)

        with tests.ApplicationContext(open_folder):
            with tests.DialogContext():
                self.uiactions.open_document_root()

    def testOpenDocumentRootNotDefined(self):
        from zim.gui.widgets import ErrorDialog

        self.assertIsNone(self.notebook.document_root)

        with tests.LoggingFilter('zim', 'No document root defined'):
            with tests.ApplicationContext():
                with tests.DialogContext(ErrorDialog):
                    self.uiactions.open_document_root()

    def testEditPageSource(self):
        from zim.gui.widgets import MessageDialog
        from zim.newfs import LocalFile
        from zim.gui.applications import ApplicationManager

        oldtext = self.page.dump('plain')  # trick page into caching content
        signals = tests.SignalLogger(self.page)

        def edit_page(cmd):
            file = LocalFile(cmd[-1])
            self.assertEqual(file, self.page.source_file)
            file.write('New text\n')

        manager = ApplicationManager()
        entry = manager.create('text/plain', 'test', 'test')
        manager.set_default_application('text/plain', entry)

        with tests.ApplicationContext(edit_page):
            with tests.DialogContext(MessageDialog):
                self.uiactions.edit_page_source()

        newtext = self.page.dump('plain')
        self.assertEqual(signals['storage-changed'],
                         [(True, )])  # boolean for external change
        self.assertNotEqual(oldtext, newtext)