import unittest
import json

from jsonschema import validate, ValidationError
from buildtrigger.basehandler import METADATA_SCHEMA
from buildtrigger.bitbuckethandler import get_transformed_webhook_payload as bb_webhook
from buildtrigger.bitbuckethandler import get_transformed_commit_info as bb_commit
from buildtrigger.githubhandler import get_transformed_webhook_payload as gh_webhook
from buildtrigger.gitlabhandler import get_transformed_webhook_payload as gl_webhook

class TestPrepareTrigger(unittest.TestCase):
  def assertSchema(self, filename, expected, processor, *args, **kwargs):
    with open('test/triggerjson/%s.json' % filename) as f:
      payload = json.loads(f.read())

    nargs = [payload]
    nargs.extend(args)

    created = processor(*nargs, **kwargs)
    self.assertEquals(expected, created)
    validate(created, METADATA_SCHEMA)


  def test_bitbucket_customer_payload_noauthor(self):
    expected = {
      "commit": "a0ec139843b2bb281ab21a433266ddc498e605dc",
      "ref": "refs/heads/master",
      "git_url": "git@bitbucket.org:lightsidelabs/svc-identity.git",
      "commit_info": {
        "url": "https://bitbucket.org/lightsidelabs/svc-identity/commits/a0ec139843b2bb281ab21a433266ddc498e605dc",
        "date": "2015-09-25T00:55:08+00:00",
        "message": "Update version.py to 0.1.2 [skip ci]\n\n(by utilitybelt/scripts/autotag_version.py)\n",
        "committer": {
          "username": "LightSide_CodeShip",
          "url": "https://bitbucket.org/LightSide_CodeShip/",
          "avatar_url": "https://bitbucket.org/account/LightSide_CodeShip/avatar/32/",
        },
      },
    }

    self.assertSchema('bitbucket_customer_example_noauthor', expected, bb_webhook)


  def test_bitbucket_customer_payload_tag(self):
    expected = {
      "commit": "a0ec139843b2bb281ab21a433266ddc498e605dc",
      "ref": "refs/tags/0.1.2",
      "git_url": "git@bitbucket.org:lightsidelabs/svc-identity.git",
      "commit_info": {
        "url": "https://bitbucket.org/lightsidelabs/svc-identity/commits/a0ec139843b2bb281ab21a433266ddc498e605dc",
        "date": "2015-09-25T00:55:08+00:00",
        "message": "Update version.py to 0.1.2 [skip ci]\n\n(by utilitybelt/scripts/autotag_version.py)\n",
        "committer": {
          "username": "LightSide_CodeShip",
          "url": "https://bitbucket.org/LightSide_CodeShip/",
          "avatar_url": "https://bitbucket.org/account/LightSide_CodeShip/avatar/32/",
        },
      },
    }

    self.assertSchema('bitbucket_customer_example_tag', expected, bb_webhook)


  def test_bitbucket_commit(self):
    ref = 'refs/heads/somebranch'
    default_branch = 'somebranch'
    repository_name = 'foo/bar'

    def lookup_author(_):
      return {
        'user': {
          'username': 'cooluser',
          'avatar': 'http://some/avatar/url'
        }
      }

    expected = {
      "commit": u"abdeaf1b2b4a6b9ddf742c1e1754236380435a62",
      "ref": u"refs/heads/somebranch",
      "git_url": u"git@bitbucket.org:foo/bar.git",
      "default_branch": u"somebranch",
      "commit_info": {
        "url": u"https://bitbucket.org/foo/bar/commits/abdeaf1b2b4a6b9ddf742c1e1754236380435a62",
        "date": u"2012-07-24 00:26:36",
        "message": u"making some changes\n",
        "author": {
          "url": u"https://bitbucket.org/cooluser/",
          "avatar_url": u"http://some/avatar/url",
          "username": u"cooluser",
        }
      }
    }

    self.assertSchema('bitbucket_commit', expected, bb_commit, ref, default_branch,
                      repository_name, lookup_author)

  def test_bitbucket_webhook_payload(self):
    expected = {
      "commit": u"af64ae7188685f8424040b4735ad12941b980d75",
      "ref": u"refs/heads/master",
      "git_url": u"git@bitbucket.org:jscoreos/another-repo.git",
      "commit_info": {
        "url": u"https://bitbucket.org/jscoreos/another-repo/commits/af64ae7188685f8424040b4735ad12941b980d75",
        "date": u"2015-09-10T20:40:54+00:00",
        "message": u"Dockerfile edited online with Bitbucket",
        "author": {
          "username": u"jscoreos",
          "url": u"https://bitbucket.org/jscoreos/",
          "avatar_url": u"https://bitbucket.org/account/jscoreos/avatar/32/",
        },
        "committer": {
          "username": u"jscoreos",
          "url": u"https://bitbucket.org/jscoreos/",
          "avatar_url": u"https://bitbucket.org/account/jscoreos/avatar/32/",
        },
      },
    }

    self.assertSchema('bitbucket_webhook', expected, bb_webhook)


  def test_github_webhook_payload(self):
    expected = {
      'commit': u'410f4cdf8ff09b87f245b13845e8497f90b90a4c',
      'ref': u'refs/heads/master',
      'git_url': u'git@github.com:josephschorr/anothertest.git',
      'commit_info': {
        'url': u'https://github.com/josephschorr/anothertest/commit/410f4cdf8ff09b87f245b13845e8497f90b90a4c',
        'date': u'2015-09-11T14:26:16-04:00',
        'message': u'Update Dockerfile',
        'committer': {
          'username': u'josephschorr',
        },
        'author': {
          'username': u'josephschorr',
        },
      },
    }

    self.assertSchema('github_webhook', expected, gh_webhook)


  def test_github_webhook_payload_with_lookup(self):
    expected = {
      'commit': u'410f4cdf8ff09b87f245b13845e8497f90b90a4c',
      'ref': u'refs/heads/master',
      'git_url': u'git@github.com:josephschorr/anothertest.git',
      'commit_info': {
        'url': u'https://github.com/josephschorr/anothertest/commit/410f4cdf8ff09b87f245b13845e8497f90b90a4c',
        'date': u'2015-09-11T14:26:16-04:00',
        'message': u'Update Dockerfile',
        'committer': {
          'username': u'josephschorr',
          'url': u'http://github.com/josephschorr',
          'avatar_url': u'http://some/avatar/url',
        },
        'author': {
          'username': u'josephschorr',
          'url': u'http://github.com/josephschorr',
          'avatar_url': u'http://some/avatar/url',
        },
      },
    }

    def lookup_user(_):
      return {
        'html_url': 'http://github.com/josephschorr',
        'avatar_url': 'http://some/avatar/url'
      }

    self.assertSchema('github_webhook', expected, gh_webhook, lookup_user=lookup_user)


  def test_github_webhook_payload_missing_fields_with_lookup(self):
    expected = {
      'commit': u'410f4cdf8ff09b87f245b13845e8497f90b90a4c',
      'ref': u'refs/heads/master',
      'git_url': u'git@github.com:josephschorr/anothertest.git',
      'commit_info': {
        'url': u'https://github.com/josephschorr/anothertest/commit/410f4cdf8ff09b87f245b13845e8497f90b90a4c',
        'date': u'2015-09-11T14:26:16-04:00',
        'message': u'Update Dockerfile'
      },
    }

    def lookup_user(username):
      if not username:
        raise Exception('Fail!')

      return {
        'html_url': 'http://github.com/josephschorr',
        'avatar_url': 'http://some/avatar/url'
      }

    self.assertSchema('github_webhook_missing', expected, gh_webhook, lookup_user=lookup_user)


  def test_gitlab_webhook_payload(self):
    expected = {
      'commit': u'fb88379ee45de28a0a4590fddcbd8eff8b36026e',
      'ref': u'refs/heads/master',
      'git_url': u'git@gitlab.com:jzelinskie/www-gitlab-com.git',
      'commit_info': {
        'url': u'https://gitlab.com/jzelinskie/www-gitlab-com/commit/fb88379ee45de28a0a4590fddcbd8eff8b36026e',
        'date': u'2015-08-13T19:33:18+00:00',
        'message': u'Fix link\n',
      },
    }

    self.assertSchema('gitlab_webhook', expected, gl_webhook)


  def test_github_webhook_payload_known_issue(self):
    expected = {
      "commit": "118b07121695d9f2e40a5ff264fdcc2917680870",
      "ref": "refs/heads/master",
      "git_url": "git@github.com:silas/docker-test.git",
      "commit_info": {
        "url": "https://github.com/silas/docker-test/commit/118b07121695d9f2e40a5ff264fdcc2917680870",
        "date": "2015-09-25T14:55:11-04:00",
        "message": "Fail",
      },
    }

    self.assertSchema('github_webhook_noname', expected, gh_webhook)


  def test_github_webhook_payload_missing_fields(self):
    expected = {
      'commit': u'410f4cdf8ff09b87f245b13845e8497f90b90a4c',
      'ref': u'refs/heads/master',
      'git_url': u'git@github.com:josephschorr/anothertest.git',
      'commit_info': {
        'url': u'https://github.com/josephschorr/anothertest/commit/410f4cdf8ff09b87f245b13845e8497f90b90a4c',
        'date': u'2015-09-11T14:26:16-04:00',
        'message': u'Update Dockerfile'
      },
    }

    self.assertSchema('github_webhook_missing', expected, gh_webhook)


  def test_gitlab_webhook_payload_with_lookup(self):
    expected = {
      'commit': u'fb88379ee45de28a0a4590fddcbd8eff8b36026e',
      'ref': u'refs/heads/master',
      'git_url': u'git@gitlab.com:jzelinskie/www-gitlab-com.git',
      'commit_info': {
        'url': u'https://gitlab.com/jzelinskie/www-gitlab-com/commit/fb88379ee45de28a0a4590fddcbd8eff8b36026e',
        'date': u'2015-08-13T19:33:18+00:00',
        'message': u'Fix link\n',
        'author': {
          'username': 'jzelinskie',
          'url': 'http://gitlab.com/jzelinskie',
          'avatar_url': 'http://some/avatar/url',
        },
      },
    }

    def lookup_user(_):
      return {
        'username': 'jzelinskie',
        'html_url': 'http://gitlab.com/jzelinskie',
        'avatar_url': 'http://some/avatar/url',
      }

    self.assertSchema('gitlab_webhook', expected, gl_webhook, lookup_user=lookup_user)


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