import unittest

from endpoints.notificationevent import (BuildSuccessEvent, NotificationEvent,
                                         VulnerabilityFoundEvent)
from util.morecollections import AttrDict

class TestCreate(unittest.TestCase):
  def test_create_notifications(self):
    self.assertIsNotNone(NotificationEvent.get_event('repo_push'))
    self.assertIsNotNone(NotificationEvent.get_event('build_queued'))
    self.assertIsNotNone(NotificationEvent.get_event('build_success'))
    self.assertIsNotNone(NotificationEvent.get_event('build_failure'))
    self.assertIsNotNone(NotificationEvent.get_event('build_start'))
    self.assertIsNotNone(NotificationEvent.get_event('build_cancelled'))
    self.assertIsNotNone(NotificationEvent.get_event('vulnerability_found'))


class TestShouldPerform(unittest.TestCase):
  def test_build_emptyjson(self):
    notification_data = AttrDict({
      'event_config_json': None,
    })

    # No build data at all.
    self.assertTrue(BuildSuccessEvent().should_perform({}, notification_data))

  def test_build_nofilter(self):
    notification_data = AttrDict({
      'event_config_json': '{}',
    })

    # No build data at all.
    self.assertTrue(BuildSuccessEvent().should_perform({}, notification_data))

    # With trigger metadata but no ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {},
    }, notification_data))

    # With trigger metadata and a ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/somebranch',
      },
    }, notification_data))


  def test_build_emptyfilter(self):
    notification_data = AttrDict({
      'event_config_json': '{"ref-regex": ""}',
    })

    # No build data at all.
    self.assertTrue(BuildSuccessEvent().should_perform({}, notification_data))

    # With trigger metadata but no ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {},
    }, notification_data))

    # With trigger metadata and a ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/somebranch',
      },
    }, notification_data))


  def test_build_invalidfilter(self):
    notification_data = AttrDict({
      'event_config_json': '{"ref-regex": "]["}',
    })

    # No build data at all.
    self.assertFalse(BuildSuccessEvent().should_perform({}, notification_data))

    # With trigger metadata but no ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {},
    }, notification_data))

    # With trigger metadata and a ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/somebranch',
      },
    }, notification_data))


  def test_build_withfilter(self):
    notification_data = AttrDict({
      'event_config_json': '{"ref-regex": "refs/heads/master"}',
    })

    # No build data at all.
    self.assertFalse(BuildSuccessEvent().should_perform({}, notification_data))

    # With trigger metadata but no ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {},
    }, notification_data))

    # With trigger metadata and a not-matching ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/somebranch',
      },
    }, notification_data))

    # With trigger metadata and a matching ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/master',
      },
    }, notification_data))


  def test_build_withwildcardfilter(self):
    notification_data = AttrDict({
      'event_config_json': '{"ref-regex": "refs/heads/.+"}',
    })

    # No build data at all.
    self.assertFalse(BuildSuccessEvent().should_perform({}, notification_data))

    # With trigger metadata but no ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {},
    }, notification_data))

    # With trigger metadata and a not-matching ref.
    self.assertFalse(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/tags/sometag',
      },
    }, notification_data))

    # With trigger metadata and a matching ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/master',
      },
    }, notification_data))

    # With trigger metadata and another matching ref.
    self.assertTrue(BuildSuccessEvent().should_perform({
      'trigger_metadata': {
        'ref': 'refs/heads/somebranch',
      },
    }, notification_data))


  def test_vulnerability_notification_nolevel(self):
    notification_data = AttrDict({
      'event_config_json': '{}',
    })

    # No level specified.
    self.assertTrue(VulnerabilityFoundEvent().should_perform({}, notification_data))


  def test_vulnerability_notification_nopvulninfo(self):
    notification_data = AttrDict({
      'event_config_json': '{"level": 3}',
    })

    # No vuln info.
    self.assertFalse(VulnerabilityFoundEvent().should_perform({}, notification_data))


  def test_vulnerability_notification_normal(self):
    notification_data = AttrDict({
      'event_config_json': '{"level": 3}',
    })

    info = {"vulnerability": {"priority": "Critical"}}
    self.assertTrue(VulnerabilityFoundEvent().should_perform(info, notification_data))




if __name__ == '__main__':
  unittest.main()