text: # -*- coding: utf-8 -*-
  from __future__ import with_statement
  import unittest
  import xml.etree.ElementTree as ET
  
  from nose.tools import assert_equal
  from six import u, text_type
  
  from twilio import twiml
  from twilio.twiml import TwimlException
  from twilio.twiml import Response
  
  
  class TwilioTest(unittest.TestCase):
      def strip(self, xml):
          return text_type(xml)
  
      def improperAppend(self, verb):
          self.assertRaises(TwimlException, verb.append, twiml.Say(""))
          self.assertRaises(TwimlException, verb.append, twiml.Gather())
          self.assertRaises(TwimlException, verb.append, twiml.Play(""))
          self.assertRaises(TwimlException, verb.append, twiml.Record())
          self.assertRaises(TwimlException, verb.append, twiml.Hangup())
          self.assertRaises(TwimlException, verb.append, twiml.Reject())
          self.assertRaises(TwimlException, verb.append, twiml.Redirect())
          self.assertRaises(TwimlException, verb.append, twiml.Dial())
          self.assertRaises(TwimlException, verb.append, twiml.Enqueue(""))
          self.assertRaises(TwimlException, verb.append, twiml.Queue(""))
          self.assertRaises(TwimlException, verb.append, twiml.Leave())
          self.assertRaises(TwimlException, verb.append, twiml.Conference(""))
          self.assertRaises(TwimlException, verb.append, twiml.Client(""))
          self.assertRaises(TwimlException, verb.append, twiml.Sms(""))
          self.assertRaises(TwimlException, verb.append, twiml.Pause())
  
  
  class TestResponse(TwilioTest):
  
      def testEmptyResponse(self):
          r = Response()
          assert_equal(self.strip(r), '<?xml version="1.0" encoding="UTF-8"?><Response />')
  
      def testResponseAddAttribute(self):
          r = Response(foo="bar")
          assert_equal(self.strip(r), '<?xml version="1.0" encoding="UTF-8"?><Response foo="bar" />')
  
  
  class TestSay(TwilioTest):
  
      def testEmptySay(self):
          """ should be a say with no text """
          r = Response()
          r.append(twiml.Say(""))
          assert_equal(self.strip(r), '<?xml version="1.0" encoding="UTF-8"?><Response><Say /></Response>')
  
      def testSayHelloWorld(self):
          """ should say hello monkey """
          r = Response()
          r.append(twiml.Say("Hello World"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Say>Hello World</Say></Response>')
  
      def testSayFrench(self):
          """ should say hello monkey """
          r = Response()
          r.append(twiml.Say(u("n\xe9cessaire et d'autres")))  # it works on python 2.6 with the from __future__ import unicode_literal
          assert_equal(text_type(r),
                       '<?xml version="1.0" encoding="UTF-8"?><Response><Say>n&#233;cessaire et d\'autres</Say></Response>')
  
      def testSayLoop(self):
          """ should say hello monkey and loop 3 times """
          r = Response()
          r.append(twiml.Say("Hello Monkey", loop=3))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Say loop="3">Hello Monkey</Say></Response>')
  
      def testSayLoopGreatBritian(self):
          """ should say have a woman say hello monkey and loop 3 times """
          r = Response()
          r.append(twiml.Say("Hello Monkey", language="en-gb"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Say language="en-gb">Hello Monkey</Say></Response>')
  
      def testSayLoopWoman(self):
          """ should say have a woman say hello monkey and loop 3 times """
          r = Response()
          r.append(twiml.Say("Hello Monkey", loop=3, voice=twiml.Say.WOMAN))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Say loop="3" voice="woman">Hello Monkey</Say></Response>')
  
      def testSayConvienceMethod(self):
          """ convenience method: should say have a woman say hello monkey and loop 3 times and be in french """
          r = Response()
          r.addSay("Hello Monkey", loop=3, voice=twiml.Say.MAN, language=twiml.Say.FRENCH)
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Say language="fr" loop="3" voice="man">Hello Monkey</Say></Response>')
  
      def testSayAddAttribute(self):
          """ add attribute """
          r = twiml.Say("", foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Say foo="bar" />')
  
      def testSayBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Say(""))
  
  
  class TestPlay(TwilioTest):
  
      def testEmptyPlay(self):
          """ should play hello monkey """
          r = Response()
          r.append(twiml.Play(""))
          r = self.strip(r)
          self.assertEqual(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Play /></Response>')
  
      def testPlayHello(self):
          """ should play hello monkey """
          r = Response()
          r.append(twiml.Play("http://hellomonkey.mp3"))
          r = self.strip(r)
          self.assertEqual(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Play>http://hellomonkey.mp3</Play></Response>')
  
      def testPlayHelloLoop(self):
          """ should play hello monkey loop """
          r = Response()
          r.append(twiml.Play("http://hellomonkey.mp3", loop=3))
          r = self.strip(r)
          self.assertEqual(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Play loop="3">http://hellomonkey.mp3</Play></Response>')
  
      def testPlayConvienceMethod(self):
          """ convenience method: should play hello monkey """
          r = Response()
          r.addPlay("http://hellomonkey.mp3", loop=3)
          r = self.strip(r)
          self.assertEqual(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Play loop="3">http://hellomonkey.mp3</Play></Response>')
  
      def testPlayAddAttribute(self):
          """ add attribute """
          r = twiml.Play("", foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Play foo="bar" />')
  
      def testPlayBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Play(""))
  
      def testPlayDigits(self):
          """ should play digits """
          r = Response()
          r.append(twiml.Play(digits='w123'))
          r = self.strip(r)
          self.assertEqual(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Play digits="w123" /></Response>')
  
      def testUrlOrDigitsRequired(self):
          self.assertRaises(TwimlException, twiml.Play)
  
  
  class TestRecord(TwilioTest):
  
      def testRecordEmpty(self):
          """ should record """
          r = Response()
          r.append(twiml.Record())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Record /></Response>')
  
      def testRecordActionMethod(self):
          """ should record with an action and a get method """
          r = Response()
          r.append(twiml.Record(action="example.com", method="GET"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Record action="example.com" method="GET" /></Response>')
  
      def testRecordMaxlengthFinishTimeout(self):
          """ should record with an maxlength, finishonkey, and timeout """
          r = Response()
          r.append(twiml.Record(timeout=4, finishOnKey="#", maxLength=30))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Record finishOnKey="#" maxLength="30" timeout="4" /></Response>')
  
      def testRecordTranscribeCallback(self):
          """ should record with a transcribe and transcribeCallback """
          r = Response()
          r.append(twiml.Record(transcribeCallback="example.com"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Record transcribeCallback="example.com" /></Response>')
  
      def testRecordAddAttribute(self):
          """ add attribute """
          r = twiml.Record(foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Record foo="bar" />')
  
      def testRecordBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Record())
  
  
  class TestRedirect(TwilioTest):
  
      def testRedirectEmpty(self):
          r = Response()
          r.append(twiml.Redirect())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect /></Response>')
  
      def testRedirectMethod(self):
          r = Response()
          r.append(twiml.Redirect(url="example.com", method="POST"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect method="POST">example.com</Redirect></Response>')
  
      def testRedirectMethodGetParams(self):
          r = Response()
          r.append(twiml.Redirect(url="example.com?id=34&action=hey", method="POST"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Redirect method="POST">example.com?id=34&amp;action=hey</Redirect></Response>')
  
      def testAddAttribute(self):
          """ add attribute """
          r = twiml.Redirect("", foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Redirect foo="bar" />')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Redirect())
  
  
  class TestHangup(TwilioTest):
  
      def testHangup(self):
          """ convenience: should Hangup to a url via POST """
          r = Response()
          r.append(twiml.Hangup())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Hangup /></Response>')
  
      def testHangupConvience(self):
          """ should raises exceptions for wrong appending """
          r = Response()
          r.addHangup()
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Hangup /></Response>')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Hangup())
  
  
  class TestLeave(TwilioTest):
  
      def testLeave(self):
          """ convenience: should Hangup to a url via POST """
          r = Response()
          r.append(twiml.Leave())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Leave /></Response>')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Leave())
  
  
  class TestReject(TwilioTest):
  
      def testReject(self):
          """ should be a Reject with default reason """
          r = Response()
          r.append(twiml.Reject())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Reject /></Response>')
  
      def testRejectConvenience(self):
          """ should be a Reject with reason Busy """
          r = Response()
          r.addReject(reason='busy')
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Reject reason="busy" /></Response>')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Reject())
  
  
  class TestSms(TwilioTest):
  
      def testEmpty(self):
          """ Test empty sms verb """
          r = Response()
          r.append(twiml.Sms(""))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Sms /></Response>')
  
      def testBody(self):
          """ Test hello world """
          r = Response()
          r.append(twiml.Sms("Hello, World"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Sms>Hello, World</Sms></Response>')
  
      def testToFromAction(self):
          """ Test the to, from, and status callback """
          r = Response()
          r.append(twiml.Sms("Hello, World", to=1231231234, sender=3453453456,
              statusCallback="example.com?id=34&action=hey"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Sms from="3453453456" statusCallback="example.com?id=34&amp;action=hey" to="1231231234">Hello, World</Sms></Response>')
  
      def testActionMethod(self):
          """ Test the action and method parameters on Sms """
          r = Response()
          r.append(twiml.Sms("Hello", method="POST", action="example.com?id=34&action=hey"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Sms action="example.com?id=34&amp;action=hey" method="POST">Hello</Sms></Response>')
  
      def testConvience(self):
          """ should raises exceptions for wrong appending """
          r = Response()
          r.addSms("Hello")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Sms>Hello</Sms></Response>')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Sms("Hello"))
  
  
  class TestConference(TwilioTest):
  
      def setUp(self):
          r = Response()
          with r.dial() as dial:
              dial.conference("TestConferenceAttributes", beep=False, waitUrl="",
                  startConferenceOnEnter=True, endConferenceOnExit=True)
          xml = r.toxml()
  
          # parse twiml XML string with Element Tree and inspect structure
          tree = ET.fromstring(xml)
          self.conf = tree.find(".//Conference")
  
      def test_conf_text(self):
          self.assertEqual(self.conf.text.strip(), "TestConferenceAttributes")
  
      def test_conf_beep(self):
          self.assertEqual(self.conf.get('beep'), "false")
  
      def test_conf_waiturl(self):
          self.assertEqual(self.conf.get('waitUrl'), "")
  
      def test_conf_start_conference(self):
          self.assertEqual(self.conf.get('startConferenceOnEnter'), "true")
  
      def test_conf_end_conference(self):
          self.assertEqual(self.conf.get('endConferenceOnExit'), "true")
  
  
  class TestQueue(TwilioTest):
  
      def setUp(self):
          r = Response()
          with r.dial() as dial:
              dial.queue("TestQueueAttribute", url="", method='GET')
              xml = r.toxml()
  
              # parse twiml XML string with Element Tree and inspect
              # structure
              tree = ET.fromstring(xml)
              self.conf = tree.find(".//Queue")
  
      def test_conf_text(self):
          self.assertEqual(self.conf.text.strip(), "TestQueueAttribute")
  
      def test_conf_waiturl(self):
          self.assertEqual(self.conf.get('url'), "")
  
      def test_conf_method(self):
          self.assertEqual(self.conf.get('method'), "GET")
  
  
  class TestEnqueue(TwilioTest):
  
      def setUp(self):
          r = Response()
          r.enqueue("TestEnqueueAttribute", action="act", method='GET',
                    waitUrl='wait', waitUrlMethod='POST')
          xml = r.toxml()
  
          # parse twiml XML string with Element Tree and inspect
          # structure
          tree = ET.fromstring(xml)
          self.conf = tree.find("./Enqueue")
  
      def test_conf_text(self):
          self.assertEqual(self.conf.text.strip(), "TestEnqueueAttribute")
  
      def test_conf_waiturl(self):
          self.assertEqual(self.conf.get('waitUrl'), "wait")
  
      def test_conf_method(self):
          self.assertEqual(self.conf.get('method'), "GET")
  
      def test_conf_action(self):
          self.assertEqual(self.conf.get('action'), "act")
  
      def test_conf_waitmethod(self):
          self.assertEqual(self.conf.get('waitUrlMethod'), "POST")
  
  
  class TestDial(TwilioTest):
  
      def testDial(self):
          """ should redirect the call """
          r = Response()
          r.append(twiml.Dial("1231231234"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial>1231231234</Dial></Response>')
  
      def testSip(self):
          """ should redirect the call """
          r = Response()
          d = r.dial()
          d.sip('foo@example.com')
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Sip>foo@example.com</Sip></Dial></Response>')
  
      def testSipUsernamePass(self):
          """ should redirect the call """
          r = Response()
          d = r.dial()
          d.sip('foo@example.com', username='foo', password='bar')
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Sip password="bar" username="foo">foo@example.com</Sip></Dial></Response>')
  
      def testSipUri(self):
          """ should redirect the call """
          r = Response()
          d = r.dial()
          s = d.sip()
          s.uri('foo@example.com')
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Sip><Uri>foo@example.com</Uri></Sip></Dial></Response>')
  
      def testConvienceMethod(self):
          """ should dial to a url via post """
          r = Response()
          r.addDial()
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial /></Response>')
  
      def testAddNumber(self):
          """ add a number to a dial """
          r = Response()
          d = twiml.Dial()
          d.append(twiml.Number("1231231234"))
          r.append(d)
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Number>1231231234</Number></Dial></Response>')
  
      def testAddNumberConvience(self):
          """ add a number to a dial, convience method """
          r = Response()
          d = r.addDial()
          d.addNumber("1231231234")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Number>1231231234</Number></Dial></Response>')
  
      def testAddConference(self):
          """ add a conference to a dial """
          r = Response()
          d = twiml.Dial()
          d.append(twiml.Conference("My Room"))
          r.append(d)
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Conference>My Room</Conference></Dial></Response>')
  
      def test_add_queue(self):
          """ add a queue to a dial """
          r = Response()
          d = r.dial()
          d.append(twiml.Queue("The Cute Queue"))
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Queue>The Cute Queue</Queue></Dial></Response>')
  
      def test_add_empty_client(self):
          """ add an empty client to a dial """
          r = Response()
          d = r.dial()
          d.client("")
          assert_equal(str(r), '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Client /></Dial></Response>')
  
      def test_add_client(self):
          """ add a client to a dial """
          r = Response()
          d = r.dial()
          d.client("alice")
          assert_equal(str(r), '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Client>alice</Client></Dial></Response>')
  
      def testAddConferenceConvenceMethod(self):
          """ add a conference to a dial, conviently """
          r = Response()
          d = r.addDial()
          d.addConference("My Room")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Dial><Conference>My Room</Conference></Dial></Response>')
  
      def testAddAttribute(self):
          """ add attribute """
          r = twiml.Conference("MyRoom", foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Conference foo="bar">MyRoom</Conference>')
  
      def testBadAppend(self):
          """ should raise exceptions for wrong appending """
          self.improperAppend(twiml.Conference("Hello"))
  
  
  class TestGather(TwilioTest):
  
      def testEmpty(self):
          """ a gather with nothing inside """
          r = Response()
          r.append(twiml.Gather())
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Gather /></Response>')
  
      def test_context_manager(self):
          with Response() as r:
              with r.gather() as g:
                  g.say("Hello")
  
              assert_equal(str(r), '<?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say>Hello</Say></Gather></Response>')
  
      def testNestedSayPlayPause(self):
          """ a gather with a say, play, and pause """
          r = Response()
          g = twiml.Gather()
          g.append(twiml.Say("Hey"))
          g.append(twiml.Play("hey.mp3"))
          g.append(twiml.Pause())
          r.append(g)
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say>Hey</Say><Play>hey.mp3</Play><Pause /></Gather></Response>')
  
      def testNestedSayPlayPauseConvience(self):
          """ a gather with a say, play, and pause """
          r = Response()
          g = r.addGather()
          g.addSay("Hey")
          g.addPlay("hey.mp3")
          g.addPause()
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Response><Gather><Say>Hey</Say><Play>hey.mp3</Play><Pause /></Gather></Response>')
  
      def testAddAttribute(self):
          """ add attribute """
          r = twiml.Gather(foo="bar")
          r = self.strip(r)
          assert_equal(r, '<?xml version="1.0" encoding="UTF-8"?><Gather foo="bar" />')
  
      def testNoDeclaration(self):
          """ add attribute """
          r = twiml.Gather(foo="bar")
          assert_equal(r.toxml(xml_declaration=False), '<Gather foo="bar" />')
  
      def testImproperNesting(self):
          """ bad nesting """
          verb = twiml.Gather()
          self.assertRaises(TwimlException, verb.append, twiml.Gather())
          self.assertRaises(TwimlException, verb.append, twiml.Record())
          self.assertRaises(TwimlException, verb.append, twiml.Hangup())
          self.assertRaises(TwimlException, verb.append, twiml.Redirect())
          self.assertRaises(TwimlException, verb.append, twiml.Dial())
          self.assertRaises(TwimlException, verb.append, twiml.Conference(""))
          self.assertRaises(TwimlException, verb.append, twiml.Sms(""))
  