import unittest
from pathlib import Path
from unittest.mock import patch, MagicMock

import systemd_unit

import portinus
from portinus import Service


class testService(unittest.TestCase):
    
    def setUp(self):
        self.test_dir = Path(__file__).absolute().parent
        self.test_data_dir = Path(self.test_dir).joinpath("testdata")
        self.real_app = str(self.test_data_dir.joinpath('real_app'))
        self.empty_dir = str(self.test_data_dir.joinpath('empty_dir'))
        self.non_existent_dir = str(self.test_data_dir.joinpath('i-dont-exist'))

    @patch.object(portinus, 'ComposeSource')
    @patch.object(systemd_unit, 'Unit')
    def test_init_no_source(self, fake_unit, fake_compose_source):
        service = Service('foo')
        fake_unit.assert_called_with('portinus-foo')
        fake_compose_source.assert_called_with('foo', None)

    @patch.object(portinus, 'ComposeSource')
    @patch.object(systemd_unit, 'Unit')
    def test_init_real_source(self, fake_unit, fake_compose_source):
        service = Service('foo', self.real_app)
        fake_unit.assert_called_with('portinus-foo')
        fake_compose_source.assert_called_with('foo', self.real_app)

    @patch.object(systemd_unit, 'Unit')
    @patch('os.path.isdir', return_value=True)
    def test_exists_non_existent_dir(self, fake_isdir, fake_unit):
        service = Service('foo')
        service.exists()
        self.assertTrue(fake_isdir.called)

    @patch.object(portinus.Service, 'exists', return_value=True)
    @patch.object(systemd_unit, 'Unit')
    @patch('subprocess.call')
    def test_compose(self, fake_call, fake_unit, fake_exists):
        service = Service('foo')
        service.compose(['ps'])
        fake_call.assert_called_with([service._source.service_script, 'ps'])

        service.compose(['logs', 'foo'])
        fake_call.assert_called_with([service._source.service_script, 'logs', 'foo'])

    @patch.object(systemd_unit, 'Unit')
    def test_stop(self, fake_unit):
        service = Service('foo')
        service._systemd_service = MagicMock()
        service.stop()
        self.assertTrue(service._systemd_service.stop.called)

    @patch('subprocess.check_output')
    def test_restart(self, fake_check_output):
        service = Service('foo')
        service._systemd_service.restart = MagicMock()
        service.restart()
        self.assertTrue(service._systemd_service.restart.called)

    @patch.object(systemd_unit, 'Unit')
    @patch.object(portinus.ComposeSource, 'remove')
    def test_remove(self, fake_compose_remove, fake_unit):
        service = Service('foo')
        service._systemd_service.remove = MagicMock()
        service.remove()
        self.assertTrue(fake_compose_remove.called)
        self.assertTrue(service._systemd_service.remove.called)

    @patch('subprocess.check_output')
    @patch.object(portinus.ComposeSource, 'ensure')
    @patch.object(systemd_unit.Unit, 'ensure')
    def test_ensure(self, fake_check_output, fake_compose_ensure, fake_unit_ensure):
        service = Service('foo')
        service.ensure()
        self.assertTrue(fake_compose_ensure.called)
        self.assertTrue(fake_unit_ensure.called)

    @patch('subprocess.check_output')
    def test__generate_service_file(self, fake_check_output):
        service = Service('foo')
        service_file = service._generate_service_file()
        if not '[Unit]' in service_file:
            raise(AssertionError('[Unit] not found in service_file'))

@@ -2951,16 +2951,24 @@
 t_ensure
+_success
 (self, f
@@ -2975,59 +2975,547 @@
 ake_
-check_output, fake_compose_ensure, fake_unit_ensure
+unit_ensure, fake_compose_ensure, fake_check_output):%0A        service = Service('foo')%0A        service.ensure()%0A        self.assertTrue(fake_compose_ensure.called)%0A        self.assertTrue(fake_unit_ensure.called)%0A%0A    @patch('subprocess.check_output')%0A    @patch.object(portinus.ComposeSource, 'ensure')%0A    @patch.object(systemd_unit.Unit, 'ensure')%0A    @patch.object(systemd_unit.Unit, 'stop', side_effect=FileNotFoundError)%0A    def test_ensure_did_not_exist(self, fake_unit_stop, fake_unit_ensure, fake_compose_ensure, fake_check_output
 ):%0A 

Increase coverage of service.ensure