add api tests; small fixes and cleanup (#104)
This commit is contained in:
Родитель
b7da8abad8
Коммит
b83eeff57f
|
@ -6,6 +6,9 @@ import { setIconOptions } from "office-ui-fabric-react/lib/Styling";
|
|||
import * as Enzyme from "enzyme";
|
||||
import * as Adapter from "enzyme-adapter-react-16";
|
||||
|
||||
global['Headers'] = () => {};
|
||||
window.parent.fetch = jest.fn();
|
||||
|
||||
// suppress icon warnings.
|
||||
setIconOptions({
|
||||
disableWarnings: true,
|
||||
|
|
|
@ -5579,7 +5579,6 @@
|
|||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -5598,7 +5597,6 @@
|
|||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -24,10 +24,10 @@ import { Twin, Device, DataPlaneResponse } from '../models/device';
|
|||
import { DeviceIdentity } from '../models/deviceIdentity';
|
||||
import { DigitalTwinInterfaces } from '../models/digitalTwinModels';
|
||||
|
||||
const DATAPLANE_CONTROLLER_ENDPOINT = `${CONTROLLER_API_ENDPOINT}${DATAPLANE}`;
|
||||
export const DATAPLANE_CONTROLLER_ENDPOINT = `${CONTROLLER_API_ENDPOINT}${DATAPLANE}`;
|
||||
const EVENTHUB_CONTROLLER_ENDPOINT = `${CONTROLLER_API_ENDPOINT}${EVENTHUB}`;
|
||||
const EVENTHUB_MONITOR_ENDPOINT = `${EVENTHUB_CONTROLLER_ENDPOINT}${MONITOR}`;
|
||||
const EVENTHUB_STOP_ENDPOINT = `${EVENTHUB_CONTROLLER_ENDPOINT}${STOP}`;
|
||||
export const EVENTHUB_MONITOR_ENDPOINT = `${EVENTHUB_CONTROLLER_ENDPOINT}${MONITOR}`;
|
||||
export const EVENTHUB_STOP_ENDPOINT = `${EVENTHUB_CONTROLLER_ENDPOINT}${STOP}`;
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
export interface DataPlaneRequest {
|
||||
|
@ -54,7 +54,7 @@ export interface CloudToDeviceMethodResult {
|
|||
}
|
||||
|
||||
// We can do something more sophisticated with agents and a factory
|
||||
const request = async (endpoint: string, parameters: any) => { // tslint:disable-line
|
||||
export const request = async (endpoint: string, parameters: any) => { // tslint:disable-line
|
||||
return fetch(
|
||||
endpoint,
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ const request = async (endpoint: string, parameters: any) => { // tslint:disable
|
|||
);
|
||||
};
|
||||
|
||||
const dataPlaneConnectionHelper = (parameters: DataPlaneParameters) => {
|
||||
export const dataPlaneConnectionHelper = (parameters: DataPlaneParameters) => {
|
||||
if (!parameters || !parameters.connectionString) {
|
||||
return;
|
||||
}
|
||||
|
@ -101,17 +101,13 @@ const dataPlaneResponseHelper = async (response: Response) => {
|
|||
}
|
||||
|
||||
// error case
|
||||
if (!result) {
|
||||
throw new Error();
|
||||
}
|
||||
if (result.ExceptionMessage && result.Message) {
|
||||
throw new Error(`${result.Message}: ${result.ExceptionMessage}`);
|
||||
}
|
||||
else if (!!result.ExceptionMessage || result.Message) {
|
||||
throw new Error(!!result.ExceptionMessage ? result.ExceptionMessage : result.Message);
|
||||
if (result && result.body) {
|
||||
if (result.body.Message || result.body.ExceptionMessage) {
|
||||
throw new Error(result.body.Message || result.body.ExceptionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(result);
|
||||
throw new Error();
|
||||
};
|
||||
|
||||
export const fetchDeviceTwin = async (parameters: FetchDeviceTwinParameters): Promise<Twin> => {
|
||||
|
@ -383,7 +379,7 @@ export const deleteDevices = async (parameters: DeleteDevicesParameters) => {
|
|||
const dataPlaneRequest: DataPlaneRequest = {
|
||||
body: JSON.stringify(deviceDeletionInstructions),
|
||||
hostName: connectionInfo.connectionInfo.hostName,
|
||||
httpMethod: 'post',
|
||||
httpMethod: HTTP_OPERATION_TYPES.Post,
|
||||
path: `devices`,
|
||||
sharedAccessSignature: connectionInfo.sasToken,
|
||||
};
|
||||
|
@ -419,7 +415,7 @@ export const monitorEvents = async (parameters: MonitorEventsParameters): Promis
|
|||
|
||||
export const stopMonitoringEvents = async (): Promise<void> => {
|
||||
try {
|
||||
const response = await request(EVENTHUB_STOP_ENDPOINT, {});
|
||||
await request(EVENTHUB_STOP_ENDPOINT, {});
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/***********************************************************
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License
|
||||
**********************************************************/
|
||||
import * as DigitalTwinsModelService from './digitalTwinsModelService';
|
||||
import { API_VERSION, DIGITAL_TWIN_API_VERSION } from '../../constants/apiConstants';
|
||||
import { HTTP_OPERATION_TYPES } from '../constants';
|
||||
|
||||
describe('digitalTwinsModelService', () => {
|
||||
|
||||
context('fetchModel', () => {
|
||||
const parameters = {
|
||||
expand: undefined,
|
||||
id: 'urn:azureiot:ModelDiscovery:ModelInformation:1',
|
||||
repoServiceHostName: 'canary-repo.azureiotrepository.com',
|
||||
repositoryId: 'repositoryId',
|
||||
token: 'SharedAccessSignature sr=canary-repo.azureiotrepository.com&sig=123&rid=repositoryId'
|
||||
};
|
||||
|
||||
it('calls fetch with specified parameters', () => {
|
||||
DigitalTwinsModelService.fetchModel(parameters);
|
||||
|
||||
const expandQueryString = parameters.expand ? `&expand=true` : ``;
|
||||
const repositoryQueryString = parameters.repositoryId ? `&repositoryId=${parameters.repositoryId}` : '';
|
||||
const apiVersionQuerySTring = `?${API_VERSION}${DIGITAL_TWIN_API_VERSION}`;
|
||||
const queryString = `${apiVersionQuerySTring}${expandQueryString}${repositoryQueryString}`;
|
||||
const modelIdentifier = encodeURIComponent(parameters.id);
|
||||
const resourceUrl = `https://${parameters.repoServiceHostName}/models/${modelIdentifier}${queryString}`;
|
||||
|
||||
const controllerRequest = {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': parameters.token || '',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: HTTP_OPERATION_TYPES.Get,
|
||||
uri: resourceUrl
|
||||
};
|
||||
|
||||
const fetchModelParameters = {
|
||||
body: JSON.stringify(controllerRequest),
|
||||
cache: 'no-cache',
|
||||
credentials: 'include',
|
||||
headers: new Headers({
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
method: HTTP_OPERATION_TYPES.Post
|
||||
};
|
||||
|
||||
expect(fetch).toBeCalledWith(DigitalTwinsModelService.CONTROLLER_ENDPOINT, fetchModelParameters);
|
||||
});
|
||||
|
||||
it('returns model when response is 200', async () => {
|
||||
// tslint:disable
|
||||
const model = {
|
||||
'@id': 'urn:azureiot:Client:SDKInformation:1',
|
||||
'@type': 'Interface',
|
||||
'displayName': 'Digital Twin Client SDK Information',
|
||||
'contents': [
|
||||
{
|
||||
'@type': 'Property',
|
||||
'name': 'language',
|
||||
'displayName': 'SDK Language',
|
||||
'schema': 'string',
|
||||
'description': 'The language for the Digital Twin client SDK. For example, Java.'
|
||||
},
|
||||
{
|
||||
'@type': 'Property',
|
||||
'name': 'version',
|
||||
'displayName': 'SDK Version',
|
||||
'schema': 'string',
|
||||
'description': 'Version of the Digital Twin client SDK. For example, 1.3.45.'
|
||||
},
|
||||
{
|
||||
'@type': 'Property',
|
||||
'name': 'vendor',
|
||||
'displayName': 'SDK Vendor',
|
||||
'schema': 'string',
|
||||
'description': 'Name of the vendor who authored the SDK. For example, Microsoft.'
|
||||
}
|
||||
],
|
||||
'@context': 'http://azureiot.com/v1/contexts/IoTModel.json'
|
||||
};
|
||||
const response = {
|
||||
json: () => model,
|
||||
headers: {has: () => {}},
|
||||
ok: true
|
||||
} as any;
|
||||
// tslint:enable
|
||||
jest.spyOn(window, 'fetch').mockResolvedValue(response);
|
||||
|
||||
const result = await DigitalTwinsModelService.fetchModel(parameters);
|
||||
expect(result).toEqual({
|
||||
createdOn: '',
|
||||
etag: '',
|
||||
lastUpdated: '',
|
||||
model,
|
||||
modelId: '',
|
||||
publisherId: '',
|
||||
publisherName: ''
|
||||
});
|
||||
});
|
||||
|
||||
it('throws Error when response is not OK', async () => {
|
||||
// tslint:disable
|
||||
const response = {
|
||||
ok: false,
|
||||
statusText: 'Not found'
|
||||
} as any;
|
||||
// tslint:enable
|
||||
jest.spyOn(window, 'fetch').mockResolvedValue(response);
|
||||
|
||||
await expect(DigitalTwinsModelService.fetchModel(parameters)).rejects.toThrow(new Error('Not found'));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -81,27 +81,19 @@ export interface RepoConnectionSettings {
|
|||
repositoryId?: string;
|
||||
}
|
||||
|
||||
const CONTROLLER_ENDPOINT = `${CONTROLLER_API_ENDPOINT}${MODELREPO}`;
|
||||
const CONTROLLER_PASSTHROUGH = true;
|
||||
export const CONTROLLER_ENDPOINT = `${CONTROLLER_API_ENDPOINT}${MODELREPO}`;
|
||||
const request = async (requestInit: RequestInitWithUri) => {
|
||||
if (CONTROLLER_PASSTHROUGH) {
|
||||
return fetch(
|
||||
CONTROLLER_ENDPOINT,
|
||||
{
|
||||
body: JSON.stringify(requestInit),
|
||||
cache: 'no-cache',
|
||||
credentials: 'include',
|
||||
headers: new Headers({
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
method: HTTP_OPERATION_TYPES.Post
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return fetch(
|
||||
requestInit.uri,
|
||||
requestInit
|
||||
);
|
||||
}
|
||||
return fetch(
|
||||
CONTROLLER_ENDPOINT,
|
||||
{
|
||||
body: JSON.stringify(requestInit),
|
||||
cache: 'no-cache',
|
||||
credentials: 'include',
|
||||
headers: new Headers({
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
method: HTTP_OPERATION_TYPES.Post
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@ $nav-width: 20%;
|
|||
}
|
||||
.device-content-nav-bar {
|
||||
overflow-y: auto;
|
||||
@include nav-bar;
|
||||
display: flex;
|
||||
flex-Direction: column;
|
||||
width: $nav-width;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* Licensed under the MIT License
|
||||
**********************************************************/
|
||||
.nav-label{
|
||||
font-weight: bold;
|
||||
padding-left: 10px;
|
||||
font-weight: bold !important;
|
||||
padding-left: 32px !important;
|
||||
}
|
||||
.navToggle {
|
||||
margin-left:5px;
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/***********************************************************
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License
|
||||
**********************************************************/
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
.top-nav-bar {
|
||||
position: relative;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
background-color: white;
|
||||
z-index: 10;
|
||||
@include nav-bar;
|
||||
.ms-Dropdown-container {
|
||||
@media screen and (min-width: $screenSize) {
|
||||
width: 200px;
|
||||
float: right;
|
||||
height: 50px;
|
||||
.nav-bar-language-dropdown {
|
||||
margin: 8px 8px;
|
||||
}
|
||||
.ms-Dropdown-items {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: $screenSize) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,19 +4,6 @@
|
|||
**********************************************************/
|
||||
@import 'variables';
|
||||
|
||||
@mixin nav-bar {
|
||||
min-height: 50px;
|
||||
@media screen and (min-width: $screenSize) {
|
||||
border: {
|
||||
bottom: {
|
||||
width: 1px;
|
||||
style: solid;
|
||||
color: $navBarBorderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin form-control-readonly {
|
||||
border-width: 0px;
|
||||
color: $textfield-disabled-font;
|
||||
|
|
|
@ -37,7 +37,7 @@ export const generateDataPlaneResponse = (httpRes: request.Response, body: any,
|
|||
};
|
||||
|
||||
// tslint:disable-next-line:cyclomatic-complexity
|
||||
export const processDataPlaneResponse = (httpRes: request.Response, body: any): {body: any, statusCode?: number} => { // tslint:disable-line:no-any
|
||||
export const processDataPlaneResponse = (httpRes: request.Response, body: any): {body: {body: any, headers?: any}, statusCode?: number} => { // tslint:disable-line:no-any
|
||||
if (httpRes) {
|
||||
if (httpRes.headers && httpRes.headers[DEVICE_STATUS_HEADER]) { // handles happy failure cases when error code is returned as a header
|
||||
return {
|
||||
|
|
Загрузка…
Ссылка в новой задаче