import unittest
from freeplane_importer.node import Node

from xml.etree.ElementTree import ElementTree
from xml.etree import ElementTree as etree


class TestNode(unittest.TestCase):

    def setUp(self):
        self.root = etree.fromstring("<map></map>")
        self.next_id = 0

    def __add_node(self, parent, text, attributes={}):
        self.next_id += 1
        string = '<node TEXT="' + text + '" ID="ID_' + str(self.next_id) + '">'

        for name, value in attributes.items():
            string += '<attribute NAME="' + name + '" VALUE="' + value + '"/>'

        string += '</node>'
        node = etree.fromstring(string)
        parent.append(node)
        return node

    def test_it_should_extract_the_deck_from_the_nearest_ancestor_of_the_node(self):
        node1 = self.__add_node(self.root, 'Root node', {
                                'anki:deck': 'root_deck'})
        node2 = self.__add_node(node1, 'Blah', {'anki:deck': 'parent_deck'})
        node3 = self.__add_node(node2, 'Blah')
        fp_node = Node(self.root, node3)

        self.assertEqual('parent_deck', fp_node.get_deck())

    def test_it_should_extract_the_model_from_the_anki_model_attribute(self):
        node = self.__add_node(self.root, 'Root node', {'anki:model': 'Basic'})
        fp_node = Node(self.root, node)

        self.assertEqual('Basic', fp_node.get_model())

    def test_it_should_extract_the_id_from_the_node(self):
        node = self.__add_node(self.root, 'Root node', {'anki:model': 'Basic'})
        fp_node = Node(self.root, node)

        self.assertEqual('ID_1', fp_node.get_node_id())

    def test_it_should_extract_fields_from_the_anki_field_wildcard_attribute(self):
        node = self.__add_node(self.root, 'Foo', {'anki:field:Bar': 'Baz'})
        fp_node = Node(self.root, node)

        fields = fp_node.get_fields()
        self.assertTrue('Bar' in fields,
                        "Expected field list to contain a 'Bar' key")
        self.assertEqual('Baz', fields['Bar'])

    def test_it_should_replace_the_wildcard_character_with_the_node_text(self):
        node = self.__add_node(
            self.root, 'Foo', {'anki:field:Foo': 'Bar * Baz'})
        fp_node = Node(self.root, node)

        fields = fp_node.get_fields()
        self.assertTrue('Foo' in fields,
                        "Expected field list to contain a 'Foo' key")
        self.assertEqual('Bar Foo Baz', fields['Foo'])

    def test_it_should_extract_the_node_text(self):
        text = 'This is the node text'
        node = self.__add_node(self.root, text, {'anki:field': 'Name'})
        fp_node = Node(self.root, node)
        self.assertEqual(text, fp_node.get_text())

    def test_it_should_extract_fields_from_child_nodes(self):
        parent = self.__add_node(self.root, '', {
                                 'anki:field:Front': 'This is the front'})
        self.__add_node(parent, '', {
                                'anki:field:Back': 'This is the back'})
        fp_node = Node(self.root, parent)
        fields = fp_node.get_fields()

        self.assertEqual('This is the back', fields['Back'])

    def test_it_should_extract_fields_from_nested_child_nodes(self):
        parent = self.__add_node(self.root, '', {
                                 'anki:field:Front': 'This is the front'})
        middle = self.__add_node(
            parent, 'This does not define a field, but it has a child that does')

        self.__add_node(middle, '', {
                                'anki:field:Back': 'This is the back'})

        fp_node = Node(self.root, parent)
        fields = fp_node.get_fields()

        self.assertEqual('This is the back', fields['Back'])

    def test_it_should_not_extract_fields_from_sub_notes(self):
        parent = self.__add_node(self.root, 'This is the parent node')
        sub_note = self.__add_node(parent, 'This is another note', {
                                   'anki:model': 'Basic'})
        self.__add_node(
            sub_note, '', {'anki:field:SubNote': 'This should be ignored'})

        fp_node = Node(self.root, parent)
        fields = fp_node.get_fields()

        self.assertFalse('SubNote' in fields)

@@ -309,22 +309,16 @@
  parent,
- text,
  attribu
@@ -323,16 +323,25 @@
 butes=%7B%7D
+, text=''
 ):%0A     
@@ -818,55 +818,9 @@
 ot, 
-'Root node', %7B%0A                                
+%7B
 'ank
@@ -884,16 +884,8 @@
 de1,
- 'Blah',
  %7B'a
@@ -952,16 +952,8 @@
 ode2
-, 'Blah'
 )%0A  
@@ -1168,37 +1168,24 @@
 e(self.root,
- 'Root node',
  %7B'anki:mode
@@ -1399,21 +1399,8 @@
 oot,
- 'Root node',
  %7B'a
@@ -1636,39 +1636,32 @@
 _node(self.root,
- 'Foo',
  %7B'anki:field:Ba
@@ -2048,15 +2048,8 @@
 oot,
- 'Foo',
  %7B'a
@@ -2072,24 +2072,31 @@
 'Bar * Baz'%7D
+, 'Foo'
 )%0A        fp
@@ -2467,14 +2467,8 @@
 oot,
- text,
  %7B'a
@@ -2486,16 +2486,22 @@
  'Name'%7D
+, text
 )%0A      
@@ -2683,36 +2683,32 @@
 _node(self.root,
- '',
  %7B%0A             
@@ -2805,34 +2805,10 @@
 nt, 
-'', %7B%0A                    
+%7B%0A
     
@@ -3110,20 +3110,16 @@
 lf.root,
- '',
  %7B%0A     
@@ -3180,32 +3180,33 @@
 is the front'%7D)%0A
+%0A
         middle =
@@ -3226,162 +3226,49 @@
 ode(
-%0A            parent, 'This does not define a field, but it has a child that does')%0A%0A        self.__add_node(middle, '', %7B%0A                                
+parent)%0A        self.__add_node(middle, %7B
 'ank
@@ -3557,35 +3557,8 @@
 root
-, 'This is the parent node'
 )%0A  
@@ -3602,69 +3602,9 @@
 nt, 
-'This is another note', %7B%0A                                   
+%7B
 'ank
@@ -3673,12 +3673,8 @@
 ote,
- '',
  %7B'a

Tidy test_node.py