import responses
import unittest

from openbadges.verifier.actions.tasks import add_task
from openbadges.verifier.openbadges_context import OPENBADGES_CONTEXT_V2_URI
from openbadges.verifier.tasks import run_task
from openbadges.verifier.tasks.task_types import VALIDATE_EXPECTED_NODE_CLASS
from openbadges.verifier.tasks.validation import OBClasses
from openbadges import verify


from .utils import set_up_context_mock, set_up_image_mock


class EndorsementTests(unittest.TestCase):
    def set_up_resources(self):
        self.assertion = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'type': 'Assertion',
            'id': 'http://example.com/assertion',
            'badge': 'http://example.com/badgeclass',
            'issuedOn': '2017-09-30T00:00Z',
            'recipient': {'identity': 'recipient@example.com', 'type': 'email', 'hashed': False},
            'verification': {
                'type': 'HostedBadge'
            }
        }
        self.badgeclass = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.com/badgeclass',
            'type': 'BadgeClass',
            'issuer': 'http://example.com/issuer',
            'endorsement': ['http://example.org/endorsement'],
            'name': 'Best Badge',
            'description': 'An achievement that is good.',
            'image': 'http://example.com/badgeimage',
            'criteria': 'http://example.com/badgecriteria'
        }
        self.issuer = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.com/issuer',
            'type': 'Profile',
            'name': 'Test Issuer',
            'email': 'test@example.com',
            'url': 'http://example.com'
        }
        self.endorsement = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.org/endorsement',
            'claim': {
                'id': self.badgeclass['id'],
                'endorsementComment': 'Pretty good'
            },
            'issuedOn': '2017-10-01T00:00Z',
            'issuer': 'http://example.org/issuer',
            'verification': {
                'type': "HostedBadge"
            }
        }
        self.endorsement_issuer = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.org/issuer',
            'type': 'Profile',
            'name': 'Test Endorser',
            'email': 'test@example.org',
            'url': 'http://example.org'
        }

    @responses.activate
    def test_discover_and_validate_claim_prop(self):
        set_up_context_mock()
        self.set_up_resources()

        for resource in [self.assertion, self.badgeclass, self.issuer, self.endorsement, self.endorsement_issuer]:
            responses.add(responses.GET, resource['id'], json=resource)
        set_up_image_mock(self.badgeclass['image'])

        results = verify(self.assertion['id'])
        self.assertTrue(results['report']['valid'])
        self.assertEqual(len(results['graph']), 5, "The graph now contains all five resources.")

    def test_claim_property_validation(self):
        self.set_up_resources()

        state = {'graph': [self.endorsement]}
        task_meta = add_task(
            VALIDATE_EXPECTED_NODE_CLASS, node_id=self.endorsement['id'], prop_name='claim',
            expected_class=OBClasses.Endorsement
        )

        result, message, actions = run_task(state, task_meta)
        self.assertTrue(result)
        claim_action = [a for a in actions if a.get('prop_name') == 'claim'][0]

        result, message, actions = run_task(state, claim_action)
        self.assertTrue(result)
        self.assertEqual(len(actions), 1)

        result, message, actions = run_task(state, actions[0])
        self.assertTrue(result)
        self.assertEqual(len(actions), 3)

@@ -1865,16 +1865,51 @@
 ement',%0A
+            'type': 'Endorsement',%0A
         
@@ -1919,24 +1919,24 @@
  'claim': %7B%0A
-
             
@@ -2558,40 +2558,35 @@
 est_
-discover_and_validate_claim_prop
+validate_linked_endorsement
 (sel
@@ -2987,24 +2987,24 @@
 %5D%5B'valid'%5D)%0A
-
         self
@@ -3089,16 +3089,545 @@
 ces.%22)%0A%0A
+    @responses.activate%0A    def test_validate_endorsement_as_input(self):%0A        set_up_context_mock()%0A        self.set_up_resources()%0A%0A        for resource in %5Bself.assertion, self.badgeclass, self.issuer, self.endorsement, self.endorsement_issuer%5D:%0A            responses.add(responses.GET, resource%5B'id'%5D, json=resource)%0A        set_up_image_mock(self.badgeclass%5B'image'%5D)%0A%0A        results = verify(self.endorsement%5B'id'%5D)%0A        self.assertTrue(results%5B'report'%5D%5B'valid'%5D)%0A        self.assertTrue(len(results%5B'graph'%5D), 2)%0A%0A
     def 

Validate endorsements as the input.