# Path: mcm/iodevices.py
# class RouterOsAPIDevice(ReadOnlyRouterOS):
# 
# 
#     def write(self, path, action, data):
#         command = self.cmd_action_join(path=path, action=action)
#         method = getattr(self, action)
#         method(command=command, data=data)
# 
# 
#     def DEL(self, command, data):
#         ID = {'.id':data['.id']}
#         try:
#             self.api.run(cmd=command, args=ID)
#         except CmdError as error:
#             raise WriteError(error)
# 
# 
#     def SET(self, command, data):
#         try:
#             self.api.run(cmd=command, args=data)
#         except CmdError as error:
#             raise WriteError(error)
# 
# 
#     def ADD(self, command, data):
#         try:
#             self.api.run(cmd=command, args=data)
#         except CmdError as error:
#             raise WriteError(error)
# 
# class StaticConfig:
# 
# 
#     def __init__(self, data):
#         self.data = data
# 
# 
#     def read(self, path):
#         for section in self.data:
#             if section['path'] == path:
#                 return section['rules']
# 
# 
#     def close(self):
#         pass
# 
# class ReadOnlyRouterOS:
# 
# 
#     def __init__(self, api):
#         self.api = api
# 
# 
#     def read(self, path):
#         cmd = self.cmd_action_join(path=path, action='GET')
#         try:
#             data = self.api.run(cmd=cmd)
#         except CmdError as error:
#             raise ReadError(error)
#         return self.filter_dynamic(data)
# 
# 
#     def write(self, path, action, data):
#         pass
# 
# 
#     def close(self):
#         self.api.close()
# 
# 
#     @staticmethod
#     def cmd_action_join(path, action):
#         actions = dict(ADD='add', SET='set', DEL='remove', GET='getall')
#         return pjoin(path, actions[action])
# 
# 
#     @staticmethod
#     def filter_dynamic(data):
#         return tuple(row for row in data if not row.get('dynamic'))
# 
# Path: mcm/librouteros/exceptions.py
# class CmdError( LibError ):
#     '''
#     Commend execution errors.
#     '''
# 
# Path: mcm/exceptions.py
# class ReadError(Exception):
#     '''
#     Exception raised when reading from master or slave occured.
#     '''
# 
# class WriteError(Exception):
#     '''
#     Exception raised when writing to master or slave occured.
#     '''


from mock import MagicMock, patch
from unittest import TestCase
from inspect import ismethod
from mcm.iodevices import RouterOsAPIDevice, StaticConfig, ReadOnlyRouterOS
from mcm.librouteros import CmdError
from mcm.exceptions import ReadError, WriteError
import pytest

    @patch.object(RouterOsAPIDevice, 'ADD')
    @patch.object(RouterOsAPIDevice, 'cmd_action_join')
    def test_write_calls_ADD_when_cmd_is_ADD(self, joinmock, addmock):
        self.TestCls.write(data='data', path=self.pathmock, action='ADD')
        addmock.assert_called_once_with(command=joinmock.return_value, data='data')

    @patch.object(RouterOsAPIDevice, 'SET')
    @patch.object(RouterOsAPIDevice, 'cmd_action_join')
    def test_write_calls_SET_when_cmd_is_SET(self, joinmock, setmock):
        self.TestCls.write(data='data', path=self.pathmock, action='SET')
        setmock.assert_called_once_with(command=joinmock.return_value, data='data')


    def test_DEL_calls_api_run_only_with_ID(self):
        data = {'.id':'*1', 'address':'1.1.1.1/24'}
        self.TestCls.DEL(command='/ip/address/remove', data=data)
        self.TestCls.api.run.assert_called_once_with(cmd='/ip/address/remove', args={'.id':'*1'})

    def test_DEL_raises_WriteError(self):
        self.TestCls.api.run.side_effect = CmdError
        with self.assertRaises(WriteError):
            self.TestCls.DEL(command=MagicMock(), data=MagicMock())

    def test_ADD_calls_api_run(self):
        data, command = MagicMock(), MagicMock()
        self.TestCls.ADD(command=command, data=data)
        self.TestCls.api.run.assert_called_once_with(cmd=command, args=data)

    def test_ADD_raises_WriteError(self):

# Path: mcm/iodevices.py
# class RouterOsAPIDevice(ReadOnlyRouterOS):
# 
# 
#     def write(self, path, action, data):
#         command = self.cmd_action_join(path=path, action=action)
#         method = getattr(self, action)
#         method(command=command, data=data)
# 
# 
#     def DEL(self, command, data):
#         ID = {'.id':data['.id']}
#         try:
#             self.api.run(cmd=command, args=ID)
#         except CmdError as error:
#             raise WriteError(error)
# 
# 
#     def SET(self, command, data):
#         try:
#             self.api.run(cmd=command, args=data)
#         except CmdError as error:
#             raise WriteError(error)
# 
# 
#     def ADD(self, command, data):
#         try:
#             self.api.run(cmd=command, args=data)
#         except CmdError as error:
#             raise WriteError(error)
# 
# class StaticConfig:
# 
# 
#     def __init__(self, data):
#         self.data = data
# 
# 
#     def read(self, path):
#         for section in self.data:
#             if section['path'] == path:
#                 return section['rules']
# 
# 
#     def close(self):
#         pass
# 
# class ReadOnlyRouterOS:
# 
# 
#     def __init__(self, api):
#         self.api = api
# 
# 
#     def read(self, path):
#         cmd = self.cmd_action_join(path=path, action='GET')
#         try:
#             data = self.api.run(cmd=cmd)
#         except CmdError as error:
#             raise ReadError(error)
#         return self.filter_dynamic(data)
# 
# 
#     def write(self, path, action, data):
#         pass
# 
# 
#     def close(self):
#         self.api.close()
# 
# 
#     @staticmethod
#     def cmd_action_join(path, action):
#         actions = dict(ADD='add', SET='set', DEL='remove', GET='getall')
#         return pjoin(path, actions[action])
# 
# 
#     @staticmethod
#     def filter_dynamic(data):
#         return tuple(row for row in data if not row.get('dynamic'))
# 
# Path: mcm/librouteros/exceptions.py
# class CmdError( LibError ):
#     '''
#     Commend execution errors.
#     '''
# 
# Path: mcm/exceptions.py
# class ReadError(Exception):
#     '''
#     Exception raised when reading from master or slave occured.
#     '''
# 
# class WriteError(Exception):
#     '''
#     Exception raised when writing to master or slave occured.
#     '''


# Path: tests/test_iodevices.py
from mock import MagicMock, patch
from unittest import TestCase
from inspect import ismethod
from mcm.iodevices import RouterOsAPIDevice, StaticConfig, ReadOnlyRouterOS
from mcm.librouteros import CmdError
from mcm.exceptions import ReadError, WriteError
import pytest


    @patch.object(RouterOsAPIDevice, 'ADD')
    @patch.object(RouterOsAPIDevice, 'cmd_action_join')
    def test_write_calls_ADD_when_cmd_is_ADD(self, joinmock, addmock):
        self.TestCls.write(data='data', path=self.pathmock, action='ADD')
        addmock.assert_called_once_with(command=joinmock.return_value, data='data')

    @patch.object(RouterOsAPIDevice, 'SET')
    @patch.object(RouterOsAPIDevice, 'cmd_action_join')
    def test_write_calls_SET_when_cmd_is_SET(self, joinmock, setmock):
        self.TestCls.write(data='data', path=self.pathmock, action='SET')
        setmock.assert_called_once_with(command=joinmock.return_value, data='data')


    def test_DEL_calls_api_run_only_with_ID(self):
        data = {'.id':'*1', 'address':'1.1.1.1/24'}
        self.TestCls.DEL(command='/ip/address/remove', data=data)
        self.TestCls.api.run.assert_called_once_with(cmd='/ip/address/remove', args={'.id':'*1'})

    def test_DEL_raises_WriteError(self):
        self.TestCls.api.run.side_effect = CmdError
        with self.assertRaises(WriteError):
            self.TestCls.DEL(command=MagicMock(), data=MagicMock())

    def test_ADD_calls_api_run(self):
        data, command = MagicMock(), MagicMock()
        self.TestCls.ADD(command=command, data=data)
        self.TestCls.api.run.assert_called_once_with(cmd=command, args=data)

    def test_ADD_raises_WriteError(self):

        self.TestCls.api.run.side_effect = CmdError