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 }