github.com/twilio/twilio-go@v1.20.1/twiml/twiml_test.go (about)

     1  package twiml_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/beevik/etree"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/twilio/twilio-go/twiml"
    10  )
    11  
    12  type MockElement struct {
    13  	name          string
    14  	text          string
    15  	optAttrs      map[string]string
    16  	paramAttrs    map[string]string
    17  	innerElements []twiml.Element
    18  }
    19  
    20  func (e MockElement) GetName() string {
    21  	return e.name
    22  }
    23  
    24  func (e MockElement) GetText() string {
    25  	return e.text
    26  }
    27  
    28  func (e MockElement) GetAttr() (map[string]string, map[string]string) {
    29  	return e.optAttrs, e.paramAttrs
    30  }
    31  
    32  func (e MockElement) GetInnerElements() []twiml.Element {
    33  	return e.innerElements
    34  }
    35  
    36  // Tests
    37  func TestCreateDocument_ReturnsResponseElement(t *testing.T) {
    38  	_, e := twiml.CreateDocument()
    39  	assert.Equal(t, "Response", e.Tag)
    40  }
    41  
    42  func TestAddAllVerbs_EmptyVerbList(t *testing.T) {
    43  	verbs := make([]twiml.Element, 0)
    44  	e := etree.Element{}
    45  	twiml.AddAllVerbs(&e, verbs)
    46  	assert.Empty(t, e.ChildElements())
    47  }
    48  
    49  func TestAddAllVerbs_VerbListOfOne(t *testing.T) {
    50  	v := MockElement{
    51  		"Gather",
    52  		"Gather things",
    53  		map[string]string{"Input": "Speech"},
    54  		map[string]string{"Action": "https://demo.twilio.com"},
    55  		[]twiml.Element{},
    56  	}
    57  	verbs := []twiml.Element{v}
    58  	resEl := etree.Element{}
    59  
    60  	twiml.AddAllVerbs(&resEl, verbs)
    61  
    62  	assertDefinesTwiMLXMLElements(t, &resEl, verbs)
    63  }
    64  
    65  func TestAddAllVerbs_ManyVerbList(t *testing.T) {
    66  	v1 := MockElement{
    67  		"Pay",
    68  		"Enter card numbers",
    69  		map[string]string{"Timeout": "10"},
    70  		map[string]string{"PaymentMethod": "ach-debit", "Description": "A description"},
    71  		[]twiml.Element{},
    72  	}
    73  	v2 := MockElement{
    74  		"Say",
    75  		"Thank you!",
    76  		map[string]string{"Voice": "alice", "Language": "en"},
    77  		map[string]string{"Loop": "1"},
    78  		[]twiml.Element{}}
    79  	verbs := []twiml.Element{v1, v2}
    80  	resEl := etree.Element{}
    81  
    82  	twiml.AddAllVerbs(&resEl, verbs)
    83  
    84  	assertDefinesTwiMLXMLElements(t, &resEl, verbs)
    85  }
    86  
    87  func TestAddAllVerbs_VerbWithManyNouns(t *testing.T) {
    88  	n1 := MockElement{
    89  		"Autopilot",
    90  		"Jarvis",
    91  		map[string]string{"Foo": "Bar"},
    92  		map[string]string{"Action": "https://demo.twilio.com", "Method": "GET"},
    93  		make([]twiml.Element, 0),
    94  	}
    95  	n2 := MockElement{
    96  		"Room",
    97  		"Conference room",
    98  		map[string]string{"participantIdentity": "Alice"},
    99  		map[string]string{},
   100  		make([]twiml.Element, 0),
   101  	}
   102  	v := MockElement{
   103  		"Connect",
   104  		"Connect things",
   105  		map[string]string{},
   106  		map[string]string{},
   107  		[]twiml.Element{n1, n2},
   108  	}
   109  	verbs := []twiml.Element{v}
   110  	resEl := etree.Element{}
   111  
   112  	twiml.AddAllVerbs(&resEl, verbs)
   113  
   114  	assertDefinesTwiMLXMLElements(t, &resEl, verbs)
   115  }
   116  
   117  func TestAddAllVerbs_VerbWithManyAttributes(t *testing.T) {
   118  	v := MockElement{
   119  		"Gather",
   120  		"Gather things",
   121  		map[string]string{
   122  			"Input":                 "Speech",
   123  			"PartialResultCallback": "https://demo.twilio.com",
   124  		},
   125  		map[string]string{
   126  			"Action": "https://demo.twilio.com",
   127  			"Method": "POST",
   128  		},
   129  		[]twiml.Element{},
   130  	}
   131  	verbs := []twiml.Element{v}
   132  	resEl := etree.Element{}
   133  
   134  	twiml.AddAllVerbs(&resEl, verbs)
   135  
   136  	assertDefinesTwiMLXMLElements(t, &resEl, verbs)
   137  }
   138  
   139  func TestToXML(t *testing.T) {
   140  	doc := etree.NewDocument()
   141  	doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
   142  	resEl := doc.CreateElement("Response")
   143  	childEl := etree.NewElement("Say")
   144  	childEl.SetText("Hello World!")
   145  	childEl.CreateAttr("Voice", "alice")
   146  	resEl.AddChild(childEl)
   147  	expected := `<?xml version="1.0" encoding="UTF-8"?><Response><Say Voice="alice">Hello World!</Say></Response>`
   148  
   149  	xml, _ := twiml.ToXML(doc)
   150  
   151  	assert.Equal(t,
   152  		expected,
   153  		xml,
   154  		"Output XML string should match expected value.")
   155  }
   156  
   157  // Utilities
   158  /*
   159  Asserts that a given XML element contains the list of TwiML Elements as
   160  child XML elements.
   161  */
   162  func assertDefinesTwiMLXMLElements(t *testing.T, el *etree.Element, elements []twiml.Element) {
   163  	assert.Equal(t,
   164  		len(elements),
   165  		len(el.ChildElements()),
   166  		"Parent element should have same number of child elements as child TwiML Elements.")
   167  
   168  	for _, element := range elements {
   169  		xmlEl := el.FindElement(element.GetName())
   170  		assert.NotNil(t,
   171  			xmlEl,
   172  			"Parent element should contain a child corresponding to the twiML element.")
   173  		assert.Equal(t, element.GetName(), xmlEl.Tag, "Child element tag should match twiML element name.")
   174  		assert.Equal(t, element.GetText(), xmlEl.Text(), "Child element text should match twiML element text.")
   175  
   176  		// Attributes
   177  		optAttrs, paramAttrs := element.GetAttr()
   178  		assertHasVerbNounAttributes(t, xmlEl, optAttrs)
   179  		assertHasVerbNounAttributes(t, xmlEl, paramAttrs)
   180  
   181  		// Nouns
   182  		assertDefinesTwiMLXMLElements(t, xmlEl, element.GetInnerElements())
   183  	}
   184  }
   185  
   186  /*
   187  Asserts that the given XML element defines attributes and their values
   188  matching the attributes in a map of TwiML element attribute name, value
   189  pairs.
   190  */
   191  func assertHasVerbNounAttributes(t *testing.T, el *etree.Element, attrs map[string]string) {
   192  	for k, v := range attrs {
   193  		name := toFirstCharacterLowerCase(k) // TwiML XML attribute names are lower camelcase
   194  		attr := el.SelectAttr(name)
   195  		assert.NotNil(t, attr, "Element should define the verb attribute.")
   196  		assert.Equal(t, v, attr.Value, "Element attribute value should match verb attribute value.")
   197  	}
   198  }
   199  
   200  /*
   201  Makes the first character of the given string lower case and returns the value
   202  as a new string.
   203  */
   204  func toFirstCharacterLowerCase(s string) string {
   205  	return strings.ToLower(string(s[0])) + s[1:]
   206  }