UNPKG

@microsoft.azure/autorest.testserver

Version:

This project contains a set of OpenAPI definitions and a server implementing the corresponding API. Use this to test compliance of AutoRest generators.

585 lines (528 loc) 18.5 kB
var express = require('express'); var router = express.Router(); var util = require('util'); var utils = require('../util/utils'); var xml2js = require('xml2js'); var util = require('util'); var _ = require('underscore'); var parseXMLString = util.promisify(xml2js.parseString); var assert = require('assert'); // Expect given request body. Otherwise, 400 with comparison is returned. var expectXmlBody = function (req, res, body, coverage, testname) { var rawBody = ''; req.setEncoding('utf8'); req.on('data', function(chunk) { rawBody += chunk }); req.on('end', async function() { var actualParsedBody, expectedParsedBody; try { actualParsedBody = await parseXMLString(rawBody); expectedParsedBody = await parseXMLString(body); } catch (err) { res.status(400).end("XML parse failure: " + err.message); return; } try { assert.deepStrictEqual(actualParsedBody, expectedParsedBody); coverage[testname]++; res.status(201).end(); } catch (err) { res.status(400).header('Content-Type', 'text/plain').end(` Expected (parsed form): ${JSON.stringify(err.expected, null, 2)} Actual (parsed form): ${JSON.stringify(err.actual, null, 2)} Expected (raw form): ${body} Actual (raw form): ${rawBody} `); } }); }; var sendXmlBody = function (res, body) { res.status(200).header('Content-Type', 'application/xml').end(body); }; // sample XML bodies var body_list = `<?xml version="1.0" encoding="utf-8"?> <EnumerationResults ServiceEndpoint="https://myaccount.blob.core.windows.net/"> <MaxResults>3</MaxResults> <Containers> <Container> <Name>audio</Name> <Properties> <Last-Modified>Wed, 26 Oct 2016 20:39:39 GMT</Last-Modified> <Etag>0x8CACB9BD7C6B1B2</Etag> <PublicAccess>container</PublicAccess> </Properties> </Container> <Container> <Name>images</Name> <Properties> <Last-Modified>Wed, 26 Oct 2016 20:39:39 GMT</Last-Modified> <Etag>0x8CACB9BD7C1EEEC</Etag> </Properties> </Container> <Container> <Name>textfiles</Name> <Properties> <Last-Modified>Wed, 26 Oct 2016 20:39:39 GMT</Last-Modified> <Etag>0x8CACB9BD7BACAC3</Etag> </Properties> </Container> </Containers> <NextMarker>video</NextMarker> </EnumerationResults>`; var body_list_container = `<?xml version="1.0" encoding="utf-8"?> <EnumerationResults ContainerName="https://myaccount.blob.core.windows.net/mycontainer"> <Blobs> <Blob> <Name>blob1.txt</Name> <Url>https://myaccount.blob.core.windows.net/mycontainer/blob1.txt</Url> <Properties> <Last-Modified>Wed, 09 Sep 2009 09:20:02 GMT</Last-Modified> <Etag>0x8CBFF45D8A29A19</Etag> <Content-Length>100</Content-Length> <Content-Type>text/html</Content-Type> <Content-Encoding /> <Content-Language>en-US</Content-Language> <Content-MD5 /> <Cache-Control>no-cache</Cache-Control> <BlobType>BlockBlob</BlobType> <LeaseStatus>unlocked</LeaseStatus> </Properties> <Metadata> <Color>blue</Color> <BlobNumber>01</BlobNumber> <SomeMetadataName>SomeMetadataValue</SomeMetadataName> </Metadata> </Blob> <Blob> <Name>blob2.txt</Name> <Snapshot>2009-09-09T09:20:03.0427659Z</Snapshot> <Url>https://myaccount.blob.core.windows.net/mycontainer/blob2.txt?snapshot=2009-09-09T09%3a20%3a03.0427659Z</Url> <Properties> <Last-Modified>Wed, 09 Sep 2009 09:20:02 GMT</Last-Modified> <Etag>0x8CBFF45D8B4C212</Etag> <Content-Length>5000</Content-Length> <Content-Type>application/octet-stream</Content-Type> <Content-Encoding>gzip</Content-Encoding> <Content-Language /> <Content-MD5 /> <Cache-Control /> <BlobType>BlockBlob</BlobType> </Properties> <Metadata> <Color>green</Color> <BlobNumber>02</BlobNumber> <SomeMetadataName>SomeMetadataValue</SomeMetadataName> <x-ms-invalid-name>nasdf$@#$$</x-ms-invalid-name> </Metadata> </Blob> <Blob> <Name>blob2.txt</Name> <Snapshot>2009-09-09T09:20:03.1587543Z</Snapshot> <Url>https://myaccount.blob.core.windows.net/mycontainer/blob2.txt?snapshot=2009-09-09T09%3a20%3a03.1587543Z</Url> <Properties> <Last-Modified>Wed, 09 Sep 2009 09:20:02 GMT</Last-Modified> <Etag>0x8CBFF45D8B4C212</Etag> <Content-Length>5000</Content-Length> <Content-Type>application/octet-stream</Content-Type> <Content-Encoding>gzip</Content-Encoding> <Content-Language /> <Content-MD5 /> <Cache-Control /> <BlobType>BlockBlob</BlobType> </Properties> <Metadata> <Color>green</Color> <BlobNumber>02</BlobNumber> <SomeMetadataName>SomeMetadataValue</SomeMetadataName> </Metadata> </Blob> <Blob> <Name>blob2.txt</Name> <Url>https://myaccount.blob.core.windows.net/mycontainer/blob2.txt</Url> <Properties> <Last-Modified>Wed, 09 Sep 2009 09:20:02 GMT</Last-Modified> <Etag>0x8CBFF45D8B4C212</Etag> <Content-Length>5000</Content-Length> <Content-Type>application/octet-stream</Content-Type> <Content-Encoding>gzip</Content-Encoding> <Content-Language /> <Content-MD5 /> <Cache-Control /> <BlobType>BlockBlob</BlobType> <LeaseStatus>unlocked</LeaseStatus> </Properties> <Metadata> <Color>green</Color> <BlobNumber>02</BlobNumber> <SomeMetadataName>SomeMetadataValue</SomeMetadataName> </Metadata> </Blob> <Blob> <Name>blob3.txt</Name> <Url>https://myaccount.blob.core.windows.net/mycontainer/blob3.txt</Url> <Properties> <Last-Modified>Wed, 09 Sep 2009 09:20:03 GMT</Last-Modified> <Etag>0x8CBFF45D911FADF</Etag> <Content-Length>16384</Content-Length> <Content-Type>image/jpeg</Content-Type> <Content-Encoding /> <Content-Language /> <Content-MD5 /> <Cache-Control /> <x-ms-blob-sequence-number>3</x-ms-blob-sequence-number> <BlobType>PageBlob</BlobType> <LeaseStatus>locked</LeaseStatus> </Properties> <Metadata> <Color>yellow</Color> <BlobNumber>03</BlobNumber> <SomeMetadataName>SomeMetadataValue</SomeMetadataName> </Metadata> </Blob> </Blobs> <NextMarker /> </EnumerationResults>` var body_acl_container = `<?xml version="1.0" encoding="utf-8"?> <SignedIdentifiers> <SignedIdentifier> <Id>MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</Id> <AccessPolicy> <Start>${new Date('2009-09-28T08:49:37.123Z').toISOString()}</Start> <Expiry>${new Date('2009-09-29T08:49:37.123Z').toISOString()}</Expiry> <Permission>rwd</Permission> </AccessPolicy> </SignedIdentifier> </SignedIdentifiers>`; var body_properties_service = `<?xml version="1.0" encoding="utf-8"?> <StorageServiceProperties> <Logging> <Version>1.0</Version> <Delete>true</Delete> <Read>false</Read> <Write>true</Write> <RetentionPolicy> <Enabled>true</Enabled> <Days>7</Days> </RetentionPolicy> </Logging> <HourMetrics> <Version>1.0</Version> <Enabled>true</Enabled> <IncludeAPIs>false</IncludeAPIs> <RetentionPolicy> <Enabled>true</Enabled> <Days>7</Days> </RetentionPolicy> </HourMetrics> <MinuteMetrics> <Version>1.0</Version> <Enabled>true</Enabled> <IncludeAPIs>true</IncludeAPIs> <RetentionPolicy> <Enabled>true</Enabled> <Days>7</Days> </RetentionPolicy> </MinuteMetrics> </StorageServiceProperties>`; var xmlService = function (coverage) { coverage['StorageListContainersXML'] = 0; coverage['StorageGetServicePropertiesXML'] = 0; coverage['StoragePutServicePropertiesXML'] = 0; coverage['StorageGetContainerACLXML'] = 0; coverage['StorageListBlobsXML'] = 0; coverage['StoragePutContainerACLXML'] = 0; coverage['GetSimpleXML'] = 0; coverage['PutSimpleXML'] = 0; coverage['GetWrappedXMLList'] = 0; coverage['PutWrappedXMLList'] = 0; coverage['GetEmptyXMLList'] = 0; coverage['PutEmptyXMLList'] = 0; coverage['GetEmptyWrappedXMLList'] = 0; coverage['PutEmptyWrappedXMLList'] = 0; coverage['GetXMLListAtRoot'] = 0; coverage['PutXMLListAtRoot'] = 0; coverage['GetXMLListAtRootSingle'] = 0; coverage['PutXMLListAtRootSingle'] = 0; coverage['GetEmptyXMLListAtRoot'] = 0; coverage['PutEmptyXMLListAtRoot'] = 0; coverage['GetXMLEmptyNode'] = 0; coverage['PutXMLEmptyNode'] = 0; coverage['GetRootWithRefAndNoMetaXML'] = 0; coverage['PutRootWithRefAndNoMetaXML'] = 0; coverage['GetRootWithRefAndMetaXML'] = 0; coverage['PutRootWithRefAndMetaXML'] = 0; coverage['jsonInputInXMLSwagger'] = 0; coverage['jsonOutputInXMLSwagger'] = 0; router.get('/', function (req, res, next) { var comp = req.query.comp; var restype = req.query.restype; switch(comp) { case "list": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/list-containers2 // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/enumerating-blob-resources // Swagger: Service_ListContainers case undefined: sendXmlBody(res, body_list); coverage['StorageListContainersXML']++; break; default: res.sendStatus(404); break; } break; case "properties": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-service-properties // Swagger: Service_GetServiceProperties case "service": sendXmlBody(res, body_properties_service); coverage['StorageGetServicePropertiesXML']++; break; default: res.sendStatus(404); break; } break; default: res.sendStatus(404); break; } }); router.put('/', function (req, res, next) { var comp = req.query.comp; var restype = req.query.restype; switch(comp) { case "properties": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-blob-service-properties case "service": expectXmlBody(req, res, body_properties_service, coverage, 'StoragePutServicePropertiesXML'); break; default: res.sendStatus(404); break; } break; default: res.sendStatus(404); break; } }); router.get('/mycontainer', function (req, res, next) { var comp = req.query.comp; var restype = req.query.restype; switch(comp) { case "acl": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-container-acl case "container": sendXmlBody(res, body_acl_container); coverage['StorageGetContainerACLXML']++; break; default: res.sendStatus(404); break; } break; case "list": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/list-blobs // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/enumerating-blob-resources // Swagger: Containers_ListBlobs case "container": sendXmlBody(res, body_list_container); coverage['StorageListBlobsXML']++; break; default: res.sendStatus(404); break; } break; default: res.sendStatus(404); break; } }); router.put('/mycontainer', function (req, res, next) { var comp = req.query.comp; var restype = req.query.restype; switch(comp) { case "acl": switch(restype) { // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-container-acl case "container": expectXmlBody(req, res, body_acl_container, coverage, 'StoragePutContainerACLXML'); break; default: res.sendStatus(404); break; } break; default: res.sendStatus(404); break; } }); const simpleBody = `<?xml version='1.0' encoding='UTF-8'?> <slideshow title="Sample Slide Show" date="Date of publication" author="Yours Truly"> <slide type="all"> <title>Wake up to WonderWidgets!</title> </slide> <slide type="all"> <title>Overview</title> <item>Why WonderWidgets are great</item> <item></item> <item>Who buys WonderWidgets</item> </slide> </slideshow>`; router.get('/simple', function (req, res) { sendXmlBody(res, simpleBody); coverage['GetSimpleXML']++; }); router.put('/simple', function(req, res) { expectXmlBody(req, res, simpleBody, coverage, 'PutSimpleXML'); }); const wrappedListsBody = `<?xml version='1.0' encoding='UTF-8'?> <AppleBarrel> <GoodApples> <Apple>Fuji</Apple> <Apple>Gala</Apple> </GoodApples> <BadApples> <Apple>Red Delicious</Apple> </BadApples> </AppleBarrel>` router.get('/wrapped-lists', function (req, res) { sendXmlBody(res, wrappedListsBody); coverage['GetWrappedXMLList']++; }); router.put('/wrapped-lists', function(req, res) { expectXmlBody(req, res, wrappedListsBody, coverage, 'PutWrappedXMLList'); }); const emptyListBody = `<?xml version='1.0' encoding='UTF-8'?> <slideshow/>`; router.get('/empty-list', function (req, res) { sendXmlBody(res, emptyListBody); coverage['GetEmptyXMLList']++; }); router.put('/empty-list', function (req, res) { expectXmlBody(req, res, emptyListBody, coverage, 'PutEmptyXMLList'); }); const emptyWrappedListsBody = `<?xml version='1.0' encoding='UTF-8'?> <AppleBarrel> <GoodApples></GoodApples> <BadApples/> </AppleBarrel>`; router.get('/empty-wrapped-lists', function (req, res) { sendXmlBody(res, emptyWrappedListsBody); coverage['GetEmptyWrappedXMLList']++; }); router.put('/empty-wrapped-lists', function (req, res) { expectXmlBody(req, res, emptyWrappedListsBody, coverage, 'PutEmptyWrappedXMLList'); }); const rootListBody = `<?xml version='1.0' encoding='UTF-8'?> <bananas> <banana> <name>Cavendish</name> <flavor>Sweet</flavor> <expiration>${new Date('2018-02-28T00:40:00.123Z').toISOString()}</expiration> </banana> <banana> <name>Plantain</name> <flavor>Savory</flavor> <expiration>${new Date('2018-02-28T00:40:00.123Z').toISOString()}</expiration> </banana> </bananas>` router.get('/root-list', function (req, res) { sendXmlBody(res, rootListBody); coverage['GetXMLListAtRoot']++; }); router.put('/root-list', function(req, res) { expectXmlBody(req, res, rootListBody, coverage, 'PutXMLListAtRoot'); }); const rootListSingleItemBody = `<?xml version='1.0' encoding='UTF-8'?> <bananas> <banana> <name>Cavendish</name> <flavor>Sweet</flavor> <expiration>${new Date('2018-02-28T00:40:00.123Z').toISOString()}</expiration> </banana> </bananas>` router.get('/root-list-single-item', function (req, res) { sendXmlBody(res, rootListSingleItemBody); coverage['GetXMLListAtRootSingle']++; }); router.put('/root-list-single-item', function(req, res) { expectXmlBody(req, res, rootListSingleItemBody, coverage, 'PutXMLListAtRootSingle'); }); const emptyRootListBody = `<?xml version='1.0' encoding='UTF-8'?> <bananas/>`; router.get('/empty-root-list', function (req, res) { sendXmlBody(res, emptyRootListBody); coverage['GetEmptyXMLListAtRoot']++; }); router.put('/empty-root-list', function(req, res) { expectXmlBody(req, res, emptyRootListBody, coverage, 'PutEmptyXMLListAtRoot'); }); const emptyChildElementBody = `<?xml version='1.0' encoding='UTF-8'?> <banana> <name>Unknown Banana</name> <flavor></flavor> <expiration>${new Date('2012-02-24T00:53:52.789Z').toISOString()}</expiration> </banana>` router.get('/empty-child-element', function (req, res) { sendXmlBody(res, emptyChildElementBody); coverage['GetXMLEmptyNode']++; }); router.put('/empty-child-element', function(req, res) { expectXmlBody(req, res, emptyChildElementBody, coverage, 'PutXMLEmptyNode'); }); const complexTypeRefComplexTypeWithNoXMLmeta = `<?xml version='1.0' encoding='UTF-8'?> <RootWithRefAndNoMeta> <RefToModel> <ID>myid</ID> </RefToModel> <Something>else</Something> </RootWithRefAndNoMeta>` router.get('/complex-type-ref-no-meta', function (req, res) { coverage['GetRootWithRefAndNoMetaXML']++; sendXmlBody(res, complexTypeRefComplexTypeWithNoXMLmeta); }); router.put('/complex-type-ref-no-meta', function(req, res) { expectXmlBody(req, res, complexTypeRefComplexTypeWithNoXMLmeta, coverage, 'PutRootWithRefAndNoMetaXML'); }); const complexTypeRefComplexTypeWithXMLmeta = `<?xml version='1.0' encoding='UTF-8'?> <RootWithRefAndMeta> <XMLComplexTypeWithMeta> <ID>myid</ID> </XMLComplexTypeWithMeta> <Something>else</Something> </RootWithRefAndMeta>` router.get('/complex-type-ref-with-meta', function (req, res) { coverage['GetRootWithRefAndMetaXML']++; sendXmlBody(res, complexTypeRefComplexTypeWithXMLmeta); }); router.put('/complex-type-ref-with-meta', function(req, res) { expectXmlBody(req, res, complexTypeRefComplexTypeWithXMLmeta, coverage, 'PutRootWithRefAndMetaXML'); }); router.get('/headers', function (req, res) { res.status(200); res.setHeader("Custom-HEADER", "custom-value"); res.end(); }); router.put('/jsoninput', function (req, res, next) { if (_.isEqual(req.body, { "id": 42 })) { coverage['jsonInputInXMLSwagger']++; res.status(200).end(); } else { utils.send400(res, next, "Did not like valid req " + util.inspect(req.body)); } }); router.get('/jsonoutput', function (req, res, next) { coverage['jsonOutputInXMLSwagger']++; res.status(200).json({ "id": 42 }); }); }; xmlService.prototype.router = router; module.exports = xmlService;