Added more detailed user agent string (#223)

* Added more detailed user agent string

* Added tests for user agent

* Getting rid of file that has been renamed

* Responding to feedback

* Responding to rest of feedback

* Added nock test for user agent

* Updated tests to use assert.equal instead of assert
This commit is contained in:
damccorm 2018-09-21 09:50:38 -04:00 коммит произвёл GitHub
Родитель e88c6573c8
Коммит 7b66ae5d93
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 101 добавлений и 6 удалений

Просмотреть файл

@ -35,8 +35,9 @@ import * as rm from 'typed-rest-client/RestClient';
import vsom = require('./VsoClient');
import lim = require("./interfaces/LocationsInterfaces");
import fs = require('fs');
import crypto = require('crypto');
import fs = require('fs');
import os = require('os');
/**
* Methods to return handler objects (see handlers folder)
@ -67,6 +68,11 @@ export function getHandlerFromToken(token: string): VsoBaseInterfaces.IRequestHa
}
}
export interface IWebApiRequestSettings {
productName: string,
productVersion: string
};
// ---------------------------------------------------------------------------
// Factory to return client apis
// When new APIs are added, a method must be added here to instantiate the API
@ -86,7 +92,7 @@ export class WebApi {
* @param defaultUrl default server url to use when creating new apis from factory methods
* @param authHandler default authentication credentials to use when creating new apis from factory methods
*/
constructor(defaultUrl: string, authHandler: VsoBaseInterfaces.IRequestHandler, options?: VsoBaseInterfaces.IRequestOptions) {
constructor(defaultUrl: string, authHandler: VsoBaseInterfaces.IRequestHandler, options?: VsoBaseInterfaces.IRequestOptions, requestSettings?: IWebApiRequestSettings) {
this.serverUrl = defaultUrl;
this.authHandler = authHandler;
this.options = options || {};
@ -124,7 +130,19 @@ export class WebApi {
this.options.ignoreSslError = !!global['_vsts_task_lib_skip_cert_validation'];
}
this.rest = new rm.RestClient('vsts-node-api', null, [this.authHandler], this.options);
let userAgent: string;
const nodeApiName: string = 'azure-devops-node-api';
const nodeApiVersion: string = JSON.parse(fs.readFileSync('package.json', 'utf8')).version;
const osName: string = os.platform();
const osVersion: string = os.release();
if(requestSettings) {
userAgent = `${requestSettings.productName}/${requestSettings.productVersion} (${nodeApiName} ${nodeApiVersion}; ${osName} ${osVersion})`;
}
else {
userAgent = `${nodeApiName}/${nodeApiVersion} (${osName} ${osVersion})`;
}
this.rest = new rm.RestClient(userAgent, null, [this.authHandler], this.options);
this.vsoClient = new vsom.VsoClient(defaultUrl, this.rest);
}

7
package-lock.json сгенерированный
Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "azure-devops-node-api",
"version": "6.6.0",
"version": "6.6.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -413,6 +413,11 @@
"wrappy": "1.0.2"
}
},
"os": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz",
"integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",

Просмотреть файл

@ -24,6 +24,7 @@
],
"license": "MIT",
"dependencies": {
"os": "0.1.1",
"tunnel": "0.0.4",
"typed-rest-client": "1.0.9",
"underscore": "1.8.3"

5
samples/package-lock.json сгенерированный
Просмотреть файл

@ -7,11 +7,16 @@
"azure-devops-node-api": {
"version": "file:../_build",
"requires": {
"os": "0.1.1",
"tunnel": "0.0.4",
"typed-rest-client": "1.0.9",
"underscore": "1.8.3"
},
"dependencies": {
"os": {
"version": "0.1.1",
"bundled": true
},
"tunnel": {
"version": "0.0.4",
"bundled": true

Просмотреть файл

@ -1,8 +1,10 @@
import assert = require('assert');
import fs = require('fs');
import nock = require('nock');
import os = require('os');
import vsom = require('../../api/VsoClient');
import WebApi = require('../../api/WebApi');
import * as rm from 'typed-rest-client/RestClient';
import { resolve } from 'path';
import { ApiResourceLocation } from '../../api/interfaces/common/VsoBaseInterfaces';
describe('VSOClient Units', function () {
@ -27,7 +29,6 @@ describe('VSOClient Units', function () {
it('constructs', () => {
//Arrange
this.timeout(1000);
const baseUrl = 'https://dev.azure.com/';
const userAgent: string = "testAgent";
const rest: rm.RestClient = new rm.RestClient(userAgent, null, []);
@ -182,4 +183,69 @@ describe('VSOClient Units', function () {
//Assert
assert(res.id === "testLocation");
});
});
describe('WebApi Units', function () {
const osName: string = os.platform();
const osVersion: string = os.release();
const nodeApiName: string = 'azure-devops-node-api';
const nodeApiVersion: string = JSON.parse(fs.readFileSync('package.json', 'utf8')).version;
it('sets the user agent correctly when request settings are specified', async () => {
const myWebApi: WebApi.WebApi = new WebApi.WebApi('microsoft.com', WebApi.getBasicHandler('user', 'password'),
undefined, {productName: 'name', productVersion: '1.2.3'});
const userAgent: string = `name/1.2.3 (${nodeApiName} ${nodeApiVersion}; ${osName} ${osVersion})`;
assert.equal(userAgent, myWebApi.rest.client.userAgent, 'User agent should be: ' + userAgent);
});
it('sets the user agent correctly when request settings are not specified', async () => {
const myWebApi: WebApi.WebApi = new WebApi.WebApi('microsoft.com', WebApi.getBasicHandler('user', 'password'), undefined);
const userAgent: string = `${nodeApiName}/${nodeApiVersion} (${osName} ${osVersion})`;
assert.equal(userAgent, myWebApi.rest.client.userAgent, 'User agent should be: ' + userAgent);
});
it('connects to the server with the correct user agent when request settings are specified', async () => {
const myWebApi: WebApi.WebApi = new WebApi.WebApi('https://dev.azure.com/', WebApi.getBasicHandler('user', 'password'),
undefined, {productName: 'name', productVersion: '1.2.3'});
const userAgent: string = `name/1.2.3 (${nodeApiName} ${nodeApiVersion}; ${osName} ${osVersion})`;
nock('https://dev.azure.com/_apis/testArea', {
reqheaders: {
'accept': 'application/json',
'user-agent': userAgent
}})
.options('')
.reply(200, {
value: [{id: 'testLocation', maxVersion: '1', releasedVersion: '1', routeTemplate: 'testTemplate', area: 'testArea', resourceName: 'testName', resourceVersion: '1'}]
});
// Act
const res: vsom.ClientVersioningData = await myWebApi.vsoClient.getVersioningData('1', 'testArea', 'testLocation', {'testKey': 'testValue'}, null);
// Assert
assert.equal(res.apiVersion, '1');
assert.equal(res.requestUrl, 'https://dev.azure.com/testTemplate');
});
it('connects to the server with the correct user agent when request settings are not specified', async () => {
// Arrange
const myWebApi: WebApi.WebApi = new WebApi.WebApi('https://dev.azure.com/', WebApi.getBasicHandler('user', 'password'), null);
const userAgent: string = `${nodeApiName}/${nodeApiVersion} (${osName} ${osVersion})`;
nock('https://dev.azure.com/_apis/testArea', {
reqheaders: {
'accept': 'application/json',
'user-agent': userAgent
}})
.options('')
.reply(200, {
value: [{id: 'testLocation', maxVersion: '1', releasedVersion: '1', routeTemplate: 'testTemplate', area: 'testArea', resourceName: 'testName', resourceVersion: '1'}]
});
// Act
const res: vsom.ClientVersioningData = await myWebApi.vsoClient.getVersioningData('1', 'testArea', 'testLocation', {'testKey': 'testValue'}, null);
// Assert
assert.equal(res.apiVersion, '1');
assert.equal(res.requestUrl, 'https://dev.azure.com/testTemplate');
});
});