/* eslint-disable max-len */
import { test } from '@japa/runner'
import { DOMParser } from '@xmldom/xmldom'
import { ApiSchemaGenerator } from '../../../src/amf/ApiSchemaGenerator.js'
import { AmfLoader } from './AmfLoader.js'
import { IAmfDocument } from '../../../src/amf/definitions/Amf.js'

const loader = new AmfLoader()
const xmlMime = 'application/xml'

test.group('XML serialization', (group) => {
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
  })

  test('serializes simple scalar array', ({ assert }) => {
    // <XmlSimpleArray>
    //   <books>...</books>
    // </XmlSimpleArray>
    const shape = loader.getShape(model, 'XmlSimpleArray')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderMocked: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const objectElement = schema.getElementsByTagName('XmlSimpleArray')[0]
    assert.ok(objectElement, 'has the XmlSimpleArray element')

    const books = schema.getElementsByTagName('books')
    assert.lengthOf(books, 1, 'has single books element')
    assert.isNotEmpty(books[0].textContent!.trim(), 'has a random value')
  })

  test('serializes simple scalar array with examples', ({ assert }) => {
    // <XmlSimpleArray>
    //   <books>one</books>
    //   <books>two</books>
    //   <books>three</books>
    // </XmlSimpleArray>
    const shape = loader.getShape(model, 'XmlSimpleArray')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const objectElement = schema.getElementsByTagName('XmlSimpleArray')[0]
    assert.ok(objectElement, 'has the XmlSimpleArray element')

    const books = schema.getElementsByTagName('books')
    assert.lengthOf(books, 3, 'has all books examples')
    assert.equal(books[0].textContent!.trim(), 'one', 'has example value #1')
    assert.equal(books[1].textContent!.trim(), 'two', 'has example value #2')
    assert.equal(books[2].textContent!.trim(), 'three', 'has example value #3')
  })

  test('serializes simple scalar wrapped array', ({ assert }) => {
    // <XmlSimpleArrayWrapped>
    //   <books>
    //     <books>...</books>
    //   </books>
    // </XmlSimpleArrayWrapped>
    const shape = loader.getShape(model, 'XmlSimpleArrayWrapped')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const objectElement = schema.getElementsByTagName('XmlSimpleArrayWrapped')[0]
    assert.ok(objectElement, 'has the XmlSimpleArrayWrapped element')
    const wrapped = Array.from(objectElement.childNodes).filter((n) => n.nodeType === 1)[0] as Element
    assert.ok(wrapped, 'has the wrapped node')
    assert.equal(wrapped.localName, 'books', 'has the wrapped element name')

    const books = wrapped.getElementsByTagName('books')
    assert.equal(books.length, 1, 'has the generated books element')
    assert.isNotEmpty(books[0].textContent!.trim(), 'has a random value')
  })

  test('serializes simple scalar wrapped array with examples', ({ assert }) => {
    // <XmlSimpleArrayWrapped>
    //   <books>
    //     <books>one</books>
    //     <books>two</books>
    //     <books>three</books>
    //   </books>
    // </XmlSimpleArrayWrapped>
    const shape = loader.getShape(model, 'XmlSimpleArrayWrapped')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const objectElement = schema.getElementsByTagName('XmlSimpleArrayWrapped')[0]
    assert.ok(objectElement, 'has the XmlSimpleArrayWrapped element')

    const wrapped = Array.from(objectElement.childNodes).filter((n) => n.nodeType === 1)[0] as Element
    assert.ok(wrapped, 'has the wrapped node')

    const books = wrapped.getElementsByTagName('books')
    assert.lengthOf(books, 3, 'has all books examples')
    assert.equal(books[0].textContent!.trim(), 'one', 'has example value #1')
    assert.equal(books[1].textContent!.trim(), 'two', 'has example value #2')
    assert.equal(books[2].textContent!.trim(), 'three', 'has example value #3')
  })

  test('serializes simple properties and attributes (required only)', ({ assert }) => {
    // <XmlAttributes uuid="..." notNamedId="..." attributeWithExample="attr example value" attributeWithDefault="attr default value">
    //   <requiredProperty>...</requiredProperty>
    // </XmlAttributes>
    const shape = loader.getShape(model, 'XmlAttributes')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlAttributes')[0]
    assert.ok(root, 'has the XmlAttributes element')

    assert.isTrue(root.hasAttribute('uuid'), 'has named uuid attribute')
    assert.isNotEmpty(root.getAttribute('uuid'), 'has uuid attribute generated value')
    assert.isTrue(root.hasAttribute('notNamedId'), 'has not named notNamedId attribute')
    assert.isNotEmpty(root.getAttribute('notNamedId'), 'has notNamedId attribute generated value')
    assert.isTrue(root.hasAttribute('attributeWithExample'), 'has not named attributeWithExample attribute')
    assert.equal(
      root.getAttribute('attributeWithExample'),
      'attr example value',
      'has attributeWithExample attribute example value'
    )
    assert.isTrue(root.hasAttribute('attributeWithDefault'), 'has not named attributeWithDefault attribute')
    assert.equal(
      root.getAttribute('attributeWithDefault'),
      'attr default value',
      'has attributeWithDefault default example value'
    )
    assert.isFalse(root.hasAttribute('optionalAttribute'), 'has no optional attributes')

    const requiredProp = root.getElementsByTagName('requiredProperty')[0]
    assert.ok(requiredProp, 'has the required property')
    assert.isNotEmpty(requiredProp.textContent!.trim(), 'the required property has generated value')

    const optionalProp = root.getElementsByTagName('optionalProp')[0]
    assert.notOk(optionalProp, 'has no optional properties')
  })

  test('serializes simple properties and attributes (required and optional)', ({ assert }) => {
    // <XmlAttributes uuid="..." notNamedId="..." attributeWithExample="attr example value" attributeWithDefault="attr default value" optionalAttribute="a1s2">
    //   <optionalProperty>abcd</optionalProperty>
    //   <requiredProperty>efgh</requiredProperty>
    // </XmlAttributes>
    const shape = loader.getShape(model, 'XmlAttributes')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
      renderOptional: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlAttributes')[0]
    assert.ok(root, 'has the XmlAttributes element')

    assert.isTrue(root.hasAttribute('optionalAttribute'), 'has the optional attribute')
    assert.equal(root.getAttribute('optionalAttribute'), 'a1s2', 'has optionalAttribute example value')

    const optionalProp = root.getElementsByTagName('optionalProperty')[0]
    assert.ok(optionalProp, 'has optional properties')
    assert.equal(optionalProp.textContent!.trim(), 'abcd', 'has the optional property value')
  })

  test('serializes an object', ({ assert }) => {
    // <XmlObjectSimple>
    //   <address>
    //     <street></street>
    //     <city></city>
    //   </address>
    // </XmlObjectSimple>
    const shape = loader.getShape(model, 'XmlObjectSimple')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
      renderOptional: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlObjectSimple')[0]
    assert.ok(root, 'has the XmlObjectSimple element')

    const address = root.getElementsByTagName('address')[0]
    assert.ok(address, 'has the address element')

    const street = address.getElementsByTagName('street')[0]
    const city = address.getElementsByTagName('city')[0]
    assert.ok(street, 'has the address > street element')
    assert.ok(city, 'has the address > city element')

    assert.isNotEmpty(street.textContent!.trim(), 'street element has a value')
    assert.isNotEmpty(city.textContent!.trim(), 'city element has a value')
  })

  test('serializes an object with examples', ({ assert }) => {
    // <XmlArraySimple>
    //   <address>
    //     <street>1234 Market street</street>
    //     <city>San Francisco</city>
    //     <street>Oxford street</street>
    //     <city>London</city>
    //   </address>
    // </XmlArraySimple>
    const shape = loader.getShape(model, 'XmlArraySimple')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
      renderOptional: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlArraySimple')[0]
    assert.ok(root, 'has the XmlArraySimple element')

    const addresses = root.getElementsByTagName('address')
    assert.lengthOf(addresses, 1, 'has the property name')

    const cities = addresses[0].getElementsByTagName('city')
    const streets = addresses[0].getElementsByTagName('street')

    assert.lengthOf(cities, 2, 'has 2 city examples')
    assert.lengthOf(streets, 2, 'has 2 street examples')

    assert.equal(cities[0].textContent!.trim(), 'San Francisco')
    assert.equal(cities[1].textContent!.trim(), 'London')

    assert.equal(streets[0].textContent!.trim(), '1234 Market street')
    assert.equal(streets[1].textContent!.trim(), 'Oxford street')
  })

  test('serializes an object with wrapped examples', ({ assert }) => {
    // <XmlArraySimple>
    //   <address>
    //     <Address>
    //       <street></street>
    //       <city></city>
    //     </Address>
    //     <Address>
    //       <street></street>
    //       <city></city>
    //     </Address>
    //   </address>
    // </XmlArraySimple>
    const shape = loader.getShape(model, 'XmlArraySimpleWrapped')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
      renderOptional: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlArraySimpleWrapped')[0]
    assert.ok(root, 'has the XmlArraySimpleWrapped element')

    const property = root.getElementsByTagName('address')
    assert.lengthOf(property, 1, 'has the property name')

    const addresses = property[0].getElementsByTagName('Address')
    assert.lengthOf(addresses, 2, 'has 2 wrapped Address objects')

    const [a1, a2] = Array.from(addresses)
    const s1 = a1.getElementsByTagName('street')[0]
    const s2 = a2.getElementsByTagName('street')[0]
    const c1 = a1.getElementsByTagName('city')[0]
    const c2 = a2.getElementsByTagName('city')[0]

    assert.ok(s1, 'has example street #1')
    assert.ok(s2, 'has example street #2')
    assert.ok(c1, 'has example city #1')
    assert.ok(c2, 'has example city #2')

    assert.equal(c1.textContent!.trim(), 'San Francisco')
    assert.equal(c2.textContent!.trim(), 'London')

    assert.equal(s1.textContent!.trim(), '1234 Market street')
    assert.equal(s2.textContent!.trim(), 'Oxford street')
  })

  test('serializes an object with wrapped examples and named', ({ assert }) => {
    // <XmlArraySimpleWrappedNamed>
    //   <Residency>
    //     <Address>
    //       <street></street>
    //       <city></city>
    //     </Address>
    //   </Residency>
    // </XmlArraySimpleWrappedNamed>
    const shape = loader.getShape(model, 'XmlArraySimpleWrappedNamed')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderExamples: true,
      renderMocked: true,
      renderOptional: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlArraySimpleWrappedNamed')[0]
    assert.ok(root, 'has the XmlArraySimpleWrappedNamed element')

    const property = root.getElementsByTagName('Residency')
    assert.lengthOf(property, 1, 'has the renamed property name')

    const addresses = property[0].getElementsByTagName('Address')
    assert.lengthOf(addresses, 1, 'has 1 wrapped Address object')

    const [a1] = Array.from(addresses)
    const s1 = a1.getElementsByTagName('street')[0]
    const c1 = a1.getElementsByTagName('city')[0]

    assert.ok(s1, 'has example street #1')
    assert.ok(c1, 'has example city #1')

    assert.isNotEmpty(c1.textContent!.trim(), 'has the generated city example')
    assert.isNotEmpty(s1.textContent!.trim(), 'has the generated street example')
  })

  test('serializes required properties', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderMocked: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)
    const root = schema.getElementsByTagName('XmlSerializationObject')[0]
    assert.ok(root, 'has the root node')
    assert.isTrue(root.hasAttribute('uuid'), 'the root has the renamed id attribute')
    assert.isNotEmpty(root.getAttribute('uuid'), 'the id attribute has the default value')
    assert.isTrue(root.hasAttribute('notNamedId'), 'the root has the notNamedId attribute')
    assert.isNotEmpty(root.getAttribute('notNamedId'), 'the notNamedId attribute has the default value')
    assert.isTrue(root.hasAttribute('attributeWithExample'), 'the root has the attributeWithExample attribute')
    assert.isNotEmpty(
      root.getAttribute('attributeWithExample'),
      'the attributeWithExample attribute has the default value'
    )
    assert.isTrue(root.hasAttribute('attributeWithDefault'), 'the root has the attributeWithDefault attribute')
    assert.equal(
      root.getAttribute('attributeWithDefault'),
      'attr default value',
      'the attributeWithDefault attribute has the defined value'
    )
    assert.isFalse(root.hasAttribute('invalidAttribute'), 'has no invalid attribute')
    assert.ok(root.getElementsByTagName('invalidAttribute')[0], 'the invalidAttribute is serialized as an element')
    const namespaceElement = root.getElementsByTagName('namespaceElement')[0]
    assert.ok(namespaceElement, 'has the namespaceElement element')
    assert.equal(namespaceElement.getAttribute('xmlns'), 'urn:loc.gov:books', 'has the namespace value')
    const namespaceWithPrefix = root.getElementsByTagNameNS('urn:ISBN:0-395-36341-6', 'namespaceWithPrefix')[0]
    assert.ok(namespaceWithPrefix, 'has the namespaceWithPrefix element')
    assert.equal(
      namespaceWithPrefix.getAttributeNS('http://www.w3.org/2000/xmlns/', 'isbn'),
      'urn:ISBN:0-395-36341-6',
      'has the prefixed namespace value'
    )
    assert.isFalse(root.hasAttribute('optionalAttribute'), 'has no optional attributes')
  })

  test('serializes optional properties', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderMocked: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlSerializationObject')[0]
    assert.ok(root, 'has the root node')
    assert.isTrue(root.hasAttribute('optionalAttribute'), 'has the optional attribute')
    assert.isNotEmpty(root.getAttribute('optionalAttribute'), 'the optional attribute has auto-value')
    assert.ok(root.getElementsByTagName('optionalProperty')[0], 'has optionalProperty element')
  })

  test('serializes optional properties with examples', async ({ assert }) => {
    /* 
    <XmlSerializationObject uuid="" notNamedId="" attributeWithExample="attr example value" attributeWithDefault="attr default value" optionalAttribute="">
      <object>
        <street></street>
        <city></city>
      </object>
      <addresses>
        <Address>
          <street></street>
          <city></city>
        </Address>
      </addresses>
      <address-array-2>
        <Address>
          <street></street>
          <city></city>
        </Address>
      </address-array-2>
      <address-array-3>
        <Address>
          <street></street>
          <city></city>
        </Address>
      </address-array-3>
      <address-array-4>
        <street></street>
        <city></city>
      </address-array-4>
      <invalidAttribute>
        <tosAccepted>false</tosAccepted>
        <newsletter>false</newsletter>
        <name>Pawel Uchida-Psztyc</name>
        <id></id>
        <age>21</age>
        <sex>male</sex>
      </invalidAttribute>
      <namespaceElement xmlns="urn:loc.gov:books">test namespace</namespaceElement>
      <isbn:namespaceWithPrefix xmlns:isbn="urn:ISBN:0-395-36341-6">test namespace</isbn:namespaceWithPrefix>
      <optionalProperty>abcd</optionalProperty>
    </XmlSerializationObject>
    */
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlSerializationObject')[0]
    assert.ok(root, 'has the root node')
    const optionalProperty = root.getElementsByTagName('optionalProperty')[0]
    assert.equal(optionalProperty.textContent!.trim(), 'abcd', 'element has an example value')
    const namespaceWithPrefix = root.getElementsByTagNameNS('urn:ISBN:0-395-36341-6', 'namespaceWithPrefix')[0]
    assert.equal(namespaceWithPrefix.textContent!.trim(), 'test namespace', 'namespace element has an example value')
    assert.equal(root.getAttribute('attributeWithExample'), 'attr example value', 'attribute has an example')
    const invalidAttr = root.getElementsByTagName('invalidAttribute')[0]
    assert.ok(invalidAttr, 'has the invalidAttribute element')
    const deep = invalidAttr.getElementsByTagName('name')[0]
    assert.equal(deep.textContent!.trim(), 'Pawel Uchida-Psztyc', 'deep elements have examples')
  })

  test('wraps an array via the XML serialization', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)
    /* 
    <addresses>
      <Address>
        <street></street>
        <city></city>
      </Address>
    </addresses>
    */

    const topAddress = schema.getElementsByTagName('addresses')[0]
    assert.ok(topAddress, 'has the wrapping "addresses" node')
    const nodes = topAddress.getElementsByTagName('Address')
    assert.lengthOf(nodes, 1, 'has a single Address')
    const node = nodes[0]
    assert.ok(node.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(node.getElementsByTagName('city')[0], 'has the street child')
  })

  test('renames wrapper and items', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <address-array-2> 
      <Address>
        <street></street>
        <city></city>
      </Address> 
    </address-array-2>
    */

    const topAddress = schema.getElementsByTagName('address-array-2')[0]
    assert.ok(topAddress, 'has the wrapping "address-array-2" node')
    const nodes = topAddress.getElementsByTagName('Address')
    assert.lengthOf(nodes, 1, 'has a single Address')
    const node = nodes[0]
    assert.ok(node.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(node.getElementsByTagName('city')[0], 'has the street child')
  })

  test('renames wrapper only', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <address-array-3> 
      <Address>
        <street></street>
        <city></city>
      </Address> 
    </address-array-3>
    */

    const topAddress = schema.getElementsByTagName('address-array-3')[0]
    assert.ok(topAddress, 'has the wrapping "address-array-3" node')
    const nodes = topAddress.getElementsByTagName('Address')
    assert.lengthOf(nodes, 1, 'has a single Address')
    const node = nodes[0]
    assert.ok(node.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(node.getElementsByTagName('city')[0], 'has the street child')
  })

  test('renames wrapper only', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <address-array-3> 
      <Address>
        <street></street>
        <city></city>
      </Address> 
    </address-array-3>
    */

    const topAddress = schema.getElementsByTagName('address-array-3')[0]
    assert.ok(topAddress, 'has the wrapping "address-array-3" node')
    const nodes = topAddress.getElementsByTagName('Address')
    assert.lengthOf(nodes, 1, 'has a single Address')
    const node = nodes[0]
    assert.ok(node.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(node.getElementsByTagName('city')[0], 'has the street child')
  })

  test('renames without wrapping', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <address-array-4> 
      <street></street>
      <city></city>
    </address-array-4>
    */

    const nodes = schema.getElementsByTagName('address-array-4')
    assert.lengthOf(nodes, 1, 'has a single object')
    const node = nodes[0]
    assert.ok(node.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(node.getElementsByTagName('city')[0], 'has the street child')
  })

  test('serializes complex objects', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlComplexProperty')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('XmlComplexProperty')[0]
    assert.ok(root, 'has the root element')

    const complex = root.getElementsByTagName('complex')[0]
    assert.ok(complex, 'has the complex element')
    assert.isNotEmpty(complex.getAttribute('correctedName'), 'has the property as attribute')

    const other = root.getElementsByTagName('other')[0]
    assert.ok(other, 'has the other element')
    assert.strictEqual(other.textContent!.trim(), 'some property', 'has the other property default value')
  })

  test('does not wrap an object when no serialization', async ({ assert }) => {
    const shape = loader.getShape(model, 'NoXmlSerializationObject')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    const root = schema.getElementsByTagName('NoXmlSerializationObject')[0]
    const addresses = root.getElementsByTagName('addresses')[0]
    assert.ok(addresses, 'has the addresses node')
    const nodes = addresses.getElementsByTagName('Address')
    assert.lengthOf(nodes, 0, 'has no Address')
    assert.ok(addresses.getElementsByTagName('street')[0], 'has the street child')
    assert.ok(addresses.getElementsByTagName('city')[0], 'has the street child')
  }).skip()

  test('serializes the root array', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlArray')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <XmlArray>
      <street></street>
      <city></city>
    </XmlArray>
    */

    const root = schema.getElementsByTagName('XmlArray')[0]
    assert.ok(root, 'has the XmlArray node')
    assert.lengthOf(root.childNodes, 2, 'has 2 children')
    assert.equal(root.childNodes[0].nodeName.toLowerCase(), 'street', 'has the street child')
    assert.equal(root.childNodes[1].nodeName.toLowerCase(), 'city', 'has the city child')
  }).skip()

  test('serializes wrapped and renamed root array', async ({ assert }) => {
    const shape = loader.getShape(model, 'XmlArray2')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
    })
    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)

    /*
    <addresses-array>
      <address>
        <city></city>
        <street></street>
      </address>
    </addresses-array>
    */

    const root = schema.getElementsByTagName('addresses-array')[0]
    assert.ok(root, 'has the addresses-array node')
    const item = root.getElementsByTagName('address')[0]
    assert.ok(item, 'has the wrapped item')
    assert.lengthOf(item.childNodes, 2, 'has 2 children')
    assert.equal(item.childNodes[0].nodeName.toLowerCase(), 'city', 'has the city child')
    assert.equal(item.childNodes[1].nodeName.toLowerCase(), 'street', 'has the street child')
  }).skip()

  test('serializes schema from a library', async ({ assert }) => {
    const shape = loader.getShape(model, 'LibraryRef')
    const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
      renderOptional: true,
      renderExamples: true,
      renderMocked: true,
    })

    const parser = new DOMParser()
    const schema = parser.parseFromString(String(result), xmlMime)
    const root = schema.getElementsByTagName('LibraryRef')[0]
    assert.ok(root, 'has the LibraryRef node')
    assert.equal(root.getElementsByTagName('petType')[0].textContent!.trim(), 'Doggie', 'has the child petType node')
    assert.equal(root.getElementsByTagName('sound')[0].textContent!.trim(), 'Woof', 'has the child sound node')
    assert.equal(root.getElementsByTagName('friendly')[0].textContent!.trim(), 'true', 'has the child friendly node')
    assert.isNotEmpty(root.getElementsByTagName('name')[0].textContent!.trim(), 'has the parent name node')
    assert.isNotEmpty(root.getElementsByTagName('etag')[0].textContent!.trim(), 'has the parent etag node')
  })

  // AMF has a problem with restoring this value from the ld model
  // test('serializes an xsd schema', async ({ assert }) => {
  //   const shape = loader.getShape(model, 'XmlRefSchema');
  //   const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
  //     renderOptional: true,
  //     renderExamples: true,
  //   });
  //   const parser = new DOMParser();
  //   const schema = parser.parseFromString(String(result), xmlMime);
  //   console.log(shape);
  // });

  // test('serializes an xsd schema with examples', async ({ assert }) => {
  //   const op = await store.getOperationRecursive('put', '/schemas');
  //   console.log(op.request.payloads[1].schema);
  //   // const shape = loader.getShape(model, 'XmlRefSchemaExample');
  //   // const result = ApiSchemaGenerator.asSchema(shape, xmlMime, {
  //   //   renderOptional: true,
  //   //   renderExamples: true,
  //   // });
  //   // const parser = new DOMParser();
  //   // const schema = parser.parseFromString(result, xmlMime);
  //   // console.log(result);
  // });
})
