text: import datetime
  import tzlocal
  import os
  import random
  import string
  import requests
  import unittest
  import challonge
  
  
  username = None
  api_key = None
  
  
  def _get_random_name():
      return "pychal_" + "".join(random.choice(string.ascii_lowercase) for _ in range(0, 15))
  
  
  class APITestCase(unittest.TestCase):
  
      def test_set_credentials(self):
          challonge.set_credentials(username, api_key)
          self.assertEqual(challonge.api._credentials['user'], username)
          self.assertEqual(challonge.api._credentials['api_key'], api_key)
  
      def test_get_credentials(self):
          challonge.api._credentials['user'] = username
          challonge.api._credentials['api_key'] = api_key
          self.assertEqual(challonge.get_credentials(), (username, api_key))
  
      def test_get_local_timezone(self):
          tz = challonge.get_timezone()
          local_tz = tzlocal.get_localzone()
          self.assertEqual(tz, local_tz)
  
      def test_set_get_timezone(self):
          test_tz = 'Asia/Seoul'
          challonge.set_timezone(test_tz)
          tz = challonge.get_timezone()
          self.assertEqual(str(tz), test_tz)
  
      def test_call(self):
          challonge.set_credentials(username, api_key)
          self.assertNotEqual(challonge.fetch("GET", "tournaments"), '')
  
  
  class TournamentsTestCase(unittest.TestCase):
  
      def setUp(self):
          challonge.set_credentials(username, api_key)
          self.random_name = _get_random_name()
  
          self.t = challonge.tournaments.create(self.random_name, self.random_name)
  
      def tearDown(self):
          challonge.tournaments.destroy(self.t['id'])
  
      def test_index(self):
          ts = challonge.tournaments.index()
          ts = list(filter(lambda x: x['id'] == self.t['id'], ts))
          self.assertEqual(len(ts), 1)
          self.assertEqual(self.t, ts[0])
  
      def test_index_filter_by_state(self):
          ts = challonge.tournaments.index(state="pending")
          ts = list(filter(lambda x: x['id'] == self.t['id'], ts))
          self.assertEqual(len(ts), 1)
          self.assertEqual(self.t, ts[0])
  
          ts = challonge.tournaments.index(state="in_progress")
          ts = list(filter(lambda x: x['id'] == self.t['id'], ts))
          self.assertEqual(ts, [])
  
      def test_index_filter_by_created(self):
          ts = challonge.tournaments.index(
              created_after=datetime.datetime.now().date() - datetime.timedelta(days=1))
          ts = filter(lambda x: x['id'] == self.t['id'], ts)
          self.assertTrue(self.t['id'] in map(lambda x: x['id'], ts))
  
      def test_show(self):
          self.assertEqual(challonge.tournaments.show(self.t['id']), self.t)
  
      def test_update_name(self):
          challonge.tournaments.update(self.t['id'], name="Test!")
  
          t = challonge.tournaments.show(self.t['id'])
  
          self.assertEqual(t['name'], "Test!")
          t.pop("name")
          self.t.pop("name")
  
          self.assertTrue(t['updated_at'] >= self.t['updated_at'])
          t.pop("updated_at")
          self.t.pop("updated_at")
  
          self.assertEqual(t, self.t)
  
      def test_update_private(self):
          challonge.tournaments.update(self.t['id'], private=True)
  
          t = challonge.tournaments.show(self.t['id'])
  
          self.assertEqual(t['private'], True)
  
      def test_update_type(self):
          challonge.tournaments.update(self.t['id'], tournament_type="round robin")
  
          t = challonge.tournaments.show(self.t['id'])
  
          self.assertEqual(t['tournament_type'], "round robin")
  
      def test_open(self):
          challonge.tournaments.update(self.t['id'], prediction_method=1)
          challonge.participants.create(self.t['id'], "#1")
          challonge.participants.create(self.t['id'], "#2")
  
          challonge.tournaments.open_for_predictions(self.t['id'])
  
          t = challonge.tournaments.show(self.t['id'])
          self.assertEqual(t['state'], "accepting_predictions")
  
      def test_start(self):
          # we have to add participants in order to start()
          self.assertRaises(
              challonge.ChallongeException,
              challonge.tournaments.start,
              self.t['id'])
  
          self.assertEqual(self.t['started_at'], None)
  
          challonge.participants.create(self.t['id'], "#1")
          challonge.participants.create(self.t['id'], "#2")
  
          challonge.tournaments.start(self.t['id'])
  
          t = challonge.tournaments.show(self.t['id'])
          self.assertNotEqual(t['started_at'], None)
  
      def test_finalize(self):
          challonge.participants.create(self.t['id'], "#1")
          challonge.participants.create(self.t['id'], "#2")
  
          challonge.tournaments.start(self.t['id'])
          ms = challonge.matches.index(self.t['id'])
          self.assertEqual(ms[0]['state'], "open")
  
          challonge.matches.update(
              self.t['id'],
              ms[0]['id'],
              scores_csv="3-2,4-1,2-2",
              winner_id=ms[0]['player1_id'])
  
          challonge.tournaments.finalize(self.t['id'])
          t = challonge.tournaments.show(self.t['id'])
  
          self.assertNotEqual(t['completed_at'], None)
  
      def test_reset(self):
          # have to add participants in order to start()
          challonge.participants.create(self.t['id'], "#1")
          challonge.participants.create(self.t['id'], "#2")
  
          challonge.tournaments.start(self.t['id'])
  
          # we can't add participants to a started tournament...
          self.assertRaises(
              challonge.ChallongeException,
              challonge.participants.create,
              self.t['id'],
              "name")
  
          challonge.tournaments.reset(self.t['id'])
  
          # but we can add participants to a reset tournament
          p = challonge.participants.create(self.t['id'], "name")
  
          challonge.participants.destroy(self.t['id'], p['id'])
  
  
  class ParticipantsTestCase(unittest.TestCase):
  
      def setUp(self):
          challonge.set_credentials(username, api_key)
          self.t_name = _get_random_name()
          self.ps_names = [_get_random_name(), _get_random_name()]
          self.t = challonge.tournaments.create(self.t_name, self.t_name)
          self.ps = challonge.participants.bulk_add(
              self.t['id'],
              self.ps_names)
  
      def tearDown(self):
          challonge.tournaments.destroy(self.t['id'])
  
      def test_index(self):
          ps = challonge.participants.index(self.t['id'])
          self.assertEqual(len(ps), 2)
  
          self.assertTrue(self.ps[0] == ps[0] or self.ps[0] == ps[1])
          self.assertTrue(self.ps[1] == ps[0] or self.ps[1] == ps[1])
  
      def test_show(self):
          p1 = challonge.participants.show(self.t['id'], self.ps[0]['id'])
          self.assertEqual(p1['id'], self.ps[0]['id'])
  
      def test_create(self):
          new_player = challonge.participants.create(self.t['id'], _get_random_name())
          res = challonge.participants.show(self.t['id'], new_player['id'])
          self.assertEqual(res, new_player)
  
      def test_create_with_number_names(self):
          player_with_only_numbers_in_name = "".join([str(random.randint(0, 9)) for _ in range(0, 9)])
          new_player = challonge.participants.create(self.t['id'], player_with_only_numbers_in_name)
          res = challonge.participants.show(self.t['id'], new_player['id'])
          self.assertEqual(res['name'], player_with_only_numbers_in_name)
  
      def test_update(self):
          challonge.participants.update(self.t['id'], self.ps[0]['id'], misc="Test!")
          p1 = challonge.participants.show(self.t['id'], self.ps[0]['id'])
  
          self.assertEqual(p1['misc'], "Test!")
          self.ps[0].pop("misc")
          p1.pop("misc")
  
          self.assertTrue(p1['updated_at'] >= self.ps[0]['updated_at'])
          self.ps[0].pop("updated_at")
          p1.pop("updated_at")
  
          self.assertEqual(self.ps[0], p1)
  
      @unittest.skip("Skipping because of API Issues")
      def test_check_in_and_undo_check_in(self):
          timezone = challonge.get_timezone()
          # Get the local time plus 30 minutes.
          test_date = datetime.datetime.now(tz=timezone) + datetime.timedelta(minutes=30)
  
          challonge.tournaments.update(
              self.t["id"],
              check_in_duration=30,
              start_at=test_date)
  
          challonge.participants.check_in(self.t["id"], self.ps[0]["id"])
          challonge.participants.check_in(self.t["id"], self.ps[1]["id"])
  
          p1 = challonge.participants.show(self.t["id"], self.ps[0]["id"])
          p2 = challonge.participants.show(self.t["id"], self.ps[1]["id"])
  
          self.assertTrue(p1["checked_in"])
          self.assertTrue(p2["checked_in"])
  
          # check the undo process
          challonge.participants.undo_check_in(self.t["id"], self.ps[0]["id"])
          challonge.participants.undo_check_in(self.t["id"], self.ps[0]["id"])
  
          p1 = challonge.participants.show(self.t["id"], self.ps[0]["id"])
          p2 = challonge.participants.show(self.t["id"], self.ps[0]["id"])
  
          self.assertFalse(p1["checked_in"])
          self.assertFalse(p2["checked_in"])
  
      def test_destroy_before_tournament_start(self):
          # delete participant before the start of the tournament
          challonge.participants.destroy(self.t['id'], self.ps[0]['id'])
          p = challonge.participants.index(self.t['id'])
          self.assertEqual(len(p), 1)
  
      def test_destroy_after_tournament_start(self):
          # delete participant after the start of the tournament
          challonge.tournaments.start(self.t['id'])
          challonge.participants.destroy(self.t['id'], self.ps[1]['id'])
          p2 = challonge.participants.show(self.t['id'], self.ps[1]['id'])
          self.assertFalse(p2['active'])
  
      def test_randomize(self):
          # randomize has a 50% chance of actually being different than
          # current seeds, so we're just verifying that the method runs at all
          challonge.participants.randomize(self.t['id'])
  
  
  class MatchesTestCase(unittest.TestCase):
  
      def setUp(self):
          challonge.set_credentials(username, api_key)
          self.t_name = _get_random_name()
  
          self.t = challonge.tournaments.create(self.t_name, self.t_name)
          self.ps = challonge.participants.bulk_add(
              self.t['id'],
              [_get_random_name(), _get_random_name()])
          challonge.tournaments.start(self.t['id'])
  
      def tearDown(self):
          challonge.tournaments.destroy(self.t['id'])
  
      def test_index(self):
          ms = challonge.matches.index(self.t['id'])
  
          self.assertEqual(len(ms), 1)
          m = ms[0]
  
          ps = set((self.ps[0]['id'], self.ps[1]['id']))
          self.assertEqual(ps, set((m['player1_id'], m['player2_id'])))
          self.assertEqual(m['state'], "open")
  
      def test_show(self):
          ms = challonge.matches.index(self.t['id'])
          for m in ms:
              self.assertEqual(m, challonge.matches.show(self.t['id'], m['id']))
  
      def test_update_reopen(self):
          ms = challonge.matches.index(self.t['id'])
          m = ms[0]
          self.assertEqual(m['state'], "open")
  
          challonge.matches.update(
              self.t['id'],
              m['id'],
              scores_csv="3-2,4-1,2-2",
              winner_id=m['player1_id'])
  
          m = challonge.matches.show(self.t['id'], m['id'])
          self.assertEqual(m['state'], "complete")
  
          challonge.matches.reopen(self.t['id'], m['id'])
          m = challonge.matches.show(self.t['id'], m['id'])
          self.assertEqual(m['state'], "open")
  
      def test_mark_as_underway(self):
          ms = challonge.matches.index(self.t['id'])
          m = ms[0]
  
          challonge.matches.mark_as_underway(self.t['id'], m['id'])
  
          m = challonge.matches.show(self.t['id'], m['id'])
          self.assertIsInstance(m['underway_at'], datetime.datetime)
  
      def test_unmark_as_underway(self):
          ms = challonge.matches.index(self.t['id'])
          m = ms[0]
  
          challonge.matches.mark_as_underway(self.t['id'], m['id'])
          challonge.matches.unmark_as_underway(self.t['id'], m['id'])
  
          m = challonge.matches.show(self.t['id'], m['id'])
          self.assertIsNone(m['underway_at'])
  
  class AttachmentsTestCase(unittest.TestCase):
  
      def setUp(self):
          challonge.set_credentials(username, api_key)
          self.t_name = _get_random_name()
  
          self.t = challonge.tournaments.create(
              self.t_name,
              self.t_name,
              accept_attachments=True)
  
          self.ps = challonge.participants.bulk_add(
              self.t['id'],
              [_get_random_name(), _get_random_name()])
          challonge.tournaments.start(self.t['id'])
          self.match = challonge.matches.index(self.t['id'])[0]
  
      def tearDown(self):
          challonge.tournaments.destroy(self.t['id'])
  
      def test_index(self):
          challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test.com")
  
          challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test2.com")
  
          a = challonge.attachments.index(self.t['id'], self.match['id'])
          self.assertEqual(len(a), 2)
  
      def test_create_url(self):
          a = challonge.attachments.create(self.t['id'], self.match['id'], url="http://test.com")
          self.assertEqual(a['url'], "http://test.com")
  
      def test_create_description(self):
          a = challonge.attachments.create(self.t['id'], self.match['id'], description="test text!")
          self.assertEqual(a['description'], "test text!")
  
      def test_create_url_with_description(self):
          a = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test.com",
              description="just a test")
  
          self.assertEqual(a['url'], "http://test.com")
          self.assertEqual(a['description'], "just a test")
  
      @unittest.skip("Skipping because of API Issues")
      def test_create_file(self):
          image = requests.get('http://lorempixel.com/300/300/')
          a1 = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              asset=image)
  
          a2 = challonge.attachments.show(self.t['id'], self.match['id'], a1['id'])
  
          self.assertEqual(a1['asset'], a2['asset'])
  
      @unittest.skip("Skipping because of API Issues")
      def test_create_file_with_description(self):
          image = requests.get('http://lorempixel.com/300/300/')
          a1 = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              asset=image,
              description="just a test")
  
          a2 = challonge.attachments.show(self.t['id'], self.match['id'], a1['id'])
  
          self.assertEqual(a1['asset'], a2['asset'])
  
      def test_update_url(self):
          a = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test.com")
  
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a['id'],
              url="https://newtest.com")
  
          a = challonge.attachments.show(self.t['id'], self.match['id'], a['id'])
          self.assertEqual(a['url'], "https://newtest.com")
  
      def test_update_description(self):
          a = challonge.attachments.create(self.t['id'], self.match['id'], description="test text!")
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a['id'],
              description="This is an updated test!")
  
          a = challonge.attachments.show(self.t['id'], self.match['id'], a['id'])
          self.assertEqual(a['description'], "This is an updated test!")
  
      def test_update_url_with_description(self):
          a = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test.com",
              description="hello there!")
  
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a['id'],
              url="http://newtest.com",
              description="added a new url!")
          a = challonge.attachments.show(self.t['id'], self.match['id'], a['id'])
  
          self.assertEqual(a['url'], "http://newtest.com")
          self.assertEqual(a['description'], "added a new url!")
  
      @unittest.skip("Skipping because of API Issues")
      def test_update_file(self):
          image = requests.get('http://lorempixel.com/300/300/')
          a1 = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              asset=image)
  
          image = requests.get('http://lorempixel.com/300/300/')
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a1['id'],
              asset=image)
  
          a2 = challonge.attachments.show(self.t['id'], self.match['id'], a1['id'])
  
          self.assertNotEqual(a1['asset'], a2['asset'])
  
      @unittest.skip("Skipping because of API Issues")
      def test_update_file_with_description(self):
          image = requests.get('http://lorempixel.com/300/300/')
          a1 = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              asset=image,
              description="just a test")
  
          image = requests.get('http://lorempixel.com/300/300/')
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a1['id'],
              asset=image,
              description='just a second test')
  
          a2 = challonge.attachments.show(self.t['id'], self.match['id'], a1['id'])
  
          self.assertNotEqual(a1['asset'], a2['asset'])
          self.assertNotEqual(a1['description'], a2['description'])
  
      @unittest.skip("Skipping because of API Issues")
      def test_update_file_only_description(self):
          image = requests.get('http://lorempixel.com/300/300/')
          a1 = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              asset=image,
              description="just a test")
  
          image = requests.get('http://lorempixel.com/300/300/')
          challonge.attachments.update(
              self.t['id'],
              self.match['id'],
              a1['id'],
              description='just a second test')
  
          a2 = challonge.attachments.show(self.t['id'], self.match['id'], a1['id'])
  
          self.assertEqual(a1['asset'], a2['asset'])
          self.assertNotEqual(a1['description'], a2['description'])
  
      def test_destroy(self):
          a = challonge.attachments.create(
              self.t['id'],
              self.match['id'],
              url="http://test.com",
              description="just a test")
  
          challonge.attachments.destroy(self.t['id'], self.match['id'], a['id'])
          a = challonge.attachments.index(self.t['id'], self.match['id'])
  
          self.assertEqual(a, [])
  
  
  if __name__ == "__main__":
      username = os.environ.get("CHALLONGE_USER")
      api_key = os.environ.get("CHALLONGE_KEY")
      if not username or not api_key:
          raise RuntimeError("You must add CHALLONGE_USER and CHALLONGE_KEY \
              to your environment variables to run the test suite")
  
      unittest.main()
  