Merge remote-tracking branch 'powerbi/master' into release-1.15.2
This commit is contained in:
Коммит
46b6866144
|
@ -14,12 +14,11 @@ module.exports = function (config) {
|
|||
exclude: [],
|
||||
reporters: argv.debug ? ['spec', 'kjhtml'] : ['spec', 'coverage', 'kjhtml'],
|
||||
autoWatch: true,
|
||||
browsers: [argv.chrome ? 'Chrome_headless' : 'PhantomJS'],
|
||||
browsers: ["Chrome_headless"],
|
||||
plugins: [
|
||||
'karma-chrome-launcher',
|
||||
'karma-jasmine',
|
||||
'karma-spec-reporter',
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-coverage',
|
||||
'karma-jasmine-html-reporter'
|
||||
],
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "powerbi-models",
|
||||
"version": "1.12.4",
|
||||
"version": "1.15.2",
|
||||
"description": "Contains JavaScript & TypeScript object models for Microsoft Power BI JavaScript SDK. For each model there is a TypeScript interface, and a validation function to ensure and object is valid.",
|
||||
"main": "dist/models.js",
|
||||
"typings": "dist/models.d.ts",
|
||||
|
@ -61,9 +61,7 @@
|
|||
"karma-coverage": "^2.0.1",
|
||||
"karma-jasmine": "^0.3.8",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"karma-spec-reporter": "0.0.32",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"ts-loader": "^6.2.1",
|
||||
"typedoc": "^0.22.14",
|
||||
"typescript": "~4.6.0",
|
||||
|
|
103
src/models.ts
103
src/models.ts
|
@ -173,7 +173,13 @@ export interface IVisual {
|
|||
}
|
||||
|
||||
export interface IDatasetBinding {
|
||||
datasetId: string;
|
||||
datasetId?: string;
|
||||
paginatedReportBindings?: IPaginatedReportDatasetBinding[];
|
||||
}
|
||||
|
||||
export interface IPaginatedReportDatasetBinding {
|
||||
sourceDatasetId: string;
|
||||
targetDatasetId: string;
|
||||
}
|
||||
|
||||
export enum Permissions {
|
||||
|
@ -307,6 +313,10 @@ export enum MenuLocation {
|
|||
Top
|
||||
}
|
||||
|
||||
export interface IQueryNameTarget {
|
||||
queryName: string;
|
||||
}
|
||||
|
||||
export interface IBaseTarget {
|
||||
table: string;
|
||||
$schema?: string;
|
||||
|
@ -378,7 +388,9 @@ export declare type IFilterKeyTarget = (IFilterKeyColumnsTarget | IFilterKeyHier
|
|||
export declare type IFilterTarget = (IFilterColumnTarget | IFilterHierarchyTarget | IFilterMeasureTarget | INotSupportedFilterTarget | IFilterColumnAggrTarget | IFilterHierarchyAggrTarget);
|
||||
export type ITupleFilterTarget = IFilterTarget[];
|
||||
export type IIdentityFilterTarget = number[];
|
||||
export type IFilterGeneralTarget = IFilterTarget | IFilterKeyTarget | ITupleFilterTarget | IIdentityFilterTarget;
|
||||
export type IHierarchyIdentityFilterTarget = IQueryNameTarget[];
|
||||
export type IIncludeExcludeFilterTarget = IFilterTarget | (IFilterTarget | IFilterKeyTarget)[][];
|
||||
export type IFilterGeneralTarget = IFilterTarget | IFilterKeyTarget | ITupleFilterTarget | IIdentityFilterTarget | IIncludeExcludeFilterTarget | IHierarchyIdentityFilterTarget;
|
||||
export interface IFilter {
|
||||
$schema: string;
|
||||
target: IFilterGeneralTarget;
|
||||
|
@ -404,7 +416,8 @@ export interface INotSupportedFilter extends IFilter {
|
|||
}
|
||||
|
||||
export interface IIncludeExcludeFilter extends IFilter {
|
||||
values: (string | number | boolean)[];
|
||||
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType;
|
||||
target: IIncludeExcludeFilterTarget;
|
||||
isExclude: boolean;
|
||||
}
|
||||
|
||||
|
@ -452,6 +465,14 @@ export interface ITupleFilter extends IFilter {
|
|||
values: TupleValueType[];
|
||||
}
|
||||
|
||||
export interface IIncludeExcludeTargetValue {
|
||||
value: PrimitiveValueType;
|
||||
keyValues?: PrimitiveValueType[];
|
||||
}
|
||||
export type IncludeExcludePointType = IIncludeExcludeTargetValue[];
|
||||
export type IncludeExcludePointsGroupType = IncludeExcludePointType[];
|
||||
export type IncludeExcludeFilterValuesType = IncludeExcludePointsGroupType[];
|
||||
|
||||
export enum FiltersOperations {
|
||||
RemoveAll,
|
||||
ReplaceAll,
|
||||
|
@ -518,6 +539,21 @@ export interface IHierarchyFilter extends IFilter {
|
|||
hierarchyData: IHierarchyFilterNode[];
|
||||
}
|
||||
|
||||
export interface IHierarchyIdentityFilterNode<IdentityType> {
|
||||
identity: IdentityType;
|
||||
children?: IHierarchyIdentityFilterNode<IdentityType>[];
|
||||
operator: HierarchyFilterNodeOperators;
|
||||
}
|
||||
|
||||
export interface IHierarchyIdentityFilter<IdentityType> extends IFilter {
|
||||
target: IHierarchyIdentityFilterTarget;
|
||||
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[];
|
||||
}
|
||||
|
||||
export interface ISmartNarratives {
|
||||
summaryText: string;
|
||||
}
|
||||
|
||||
export enum FilterType {
|
||||
Advanced = 0,
|
||||
Basic = 1,
|
||||
|
@ -529,6 +565,7 @@ export enum FilterType {
|
|||
RelativeTime = 7,
|
||||
Identity = 8,
|
||||
Hierarchy = 9,
|
||||
HierarchyIdentity = 10,
|
||||
}
|
||||
|
||||
export enum RelativeDateFilterTimeUnit {
|
||||
|
@ -607,14 +644,16 @@ export class NotSupportedFilter extends Filter {
|
|||
|
||||
export class IncludeExcludeFilter extends Filter {
|
||||
static schemaUrl: string = "http://powerbi.com/product/schema#includeExclude";
|
||||
values: (string | number | boolean)[];
|
||||
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType;
|
||||
isExclude: boolean;
|
||||
target: IIncludeExcludeFilterTarget;
|
||||
|
||||
constructor(
|
||||
target: IFilterTarget,
|
||||
target: IIncludeExcludeFilterTarget,
|
||||
isExclude: boolean,
|
||||
values: (string | number | boolean)[]) {
|
||||
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType) {
|
||||
super(target, FilterType.IncludeExclude);
|
||||
this.target = target;
|
||||
this.values = values;
|
||||
this.isExclude = isExclude;
|
||||
this.schemaUrl = IncludeExcludeFilter.schemaUrl;
|
||||
|
@ -932,6 +971,29 @@ export class HierarchyFilter extends Filter {
|
|||
}
|
||||
}
|
||||
|
||||
export class HierarchyIdentityFilter<IdentityType> extends Filter {
|
||||
static schemaUrl: string = "http://powerbi.com/product/schema#hierarchyIdentity";
|
||||
|
||||
target: IHierarchyIdentityFilterTarget;
|
||||
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[];
|
||||
|
||||
constructor(
|
||||
target: IHierarchyIdentityFilterTarget,
|
||||
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[]
|
||||
) {
|
||||
super(target, FilterType.HierarchyIdentity);
|
||||
this.schemaUrl = HierarchyIdentityFilter.schemaUrl;
|
||||
this.hierarchyData = hierarchyData;
|
||||
}
|
||||
|
||||
toJSON(): IHierarchyIdentityFilter<IdentityType> {
|
||||
const filter = super.toJSON() as IHierarchyIdentityFilter<IdentityType>;
|
||||
filter.hierarchyData = this.hierarchyData;
|
||||
filter.target = this.target;
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IDataReference {
|
||||
target: IFilterTarget;
|
||||
}
|
||||
|
@ -1175,6 +1237,18 @@ export interface IColumnSchema {
|
|||
name: string;
|
||||
displayName?: string;
|
||||
dataType: DataType;
|
||||
aggregateFunction?: AggregateFunction;
|
||||
}
|
||||
|
||||
export enum AggregateFunction {
|
||||
Default = 1,
|
||||
None,
|
||||
Sum,
|
||||
Min,
|
||||
Max,
|
||||
Count,
|
||||
Average,
|
||||
DistinctCount
|
||||
}
|
||||
|
||||
export const enum DataType {
|
||||
|
@ -1227,6 +1301,15 @@ export interface ILocaleSettings {
|
|||
formatLocale?: string;
|
||||
}
|
||||
|
||||
export enum BrowserPrintAdjustmentsMode {
|
||||
Default,
|
||||
NoAdjustments
|
||||
}
|
||||
|
||||
export interface IPrintSettings {
|
||||
browserPrintAdjustmentsMode?: BrowserPrintAdjustmentsMode;
|
||||
}
|
||||
|
||||
export const enum ReportCreationMode {
|
||||
Default = "Default",
|
||||
QuickExplore = "QuickExplore",
|
||||
|
@ -1253,6 +1336,7 @@ export interface ISettings {
|
|||
visualSettings?: IVisualSettings;
|
||||
localeSettings?: ILocaleSettings;
|
||||
zoomLevel?: number;
|
||||
printSettings?: IPrintSettings;
|
||||
}
|
||||
|
||||
export interface IReportBars {
|
||||
|
@ -1327,6 +1411,7 @@ export interface IPaginatedReportLoadConfiguration {
|
|||
type?: string;
|
||||
embedUrl?: string;
|
||||
parameterValues?: IPaginatedReportParameter[];
|
||||
datasetBindings?: IPaginatedReportDatasetBinding[];
|
||||
}
|
||||
|
||||
export interface IPaginatedReportSettings {
|
||||
|
@ -1663,6 +1748,7 @@ export interface ICommandsSettings {
|
|||
groupVisualContainers?: ICommandSettings;
|
||||
summarize?: ICommandSettings;
|
||||
clearSelection?: ICommandSettings;
|
||||
focusMode?: ICommandSettings;
|
||||
}
|
||||
|
||||
export interface IPaginatedReportsCommandSettings {
|
||||
|
@ -1961,3 +2047,8 @@ export function validateZoomLevel(input: any): IError[] {
|
|||
const errors: any[] = Validators.zoomLevelValidator.validate(input);
|
||||
return errors ? errors.map(normalizeError) : undefined;
|
||||
}
|
||||
|
||||
export function validatePrintSettings(input: any): IError[] {
|
||||
const errors: any[] = Validators.printSettingsValidator.validate(input);
|
||||
return errors ? errors.map(normalizeError) : undefined;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
HierarchyFilterNodeValidator,
|
||||
HierarchyFilterValidator,
|
||||
IncludeExcludeFilterValidator,
|
||||
IncludeExcludePointValueValidator,
|
||||
NotSupportedFilterValidator,
|
||||
OnLoadFiltersBaseRemoveOperationValidator,
|
||||
OnLoadFiltersBaseValidator,
|
||||
|
@ -64,6 +65,8 @@ import { ArrayValidator, BooleanArrayValidator, BooleanValidator, EnumValidator,
|
|||
import { ParametersPanelValidator } from '../models/parameterPanelValidator';
|
||||
import { DatasetCreateConfigValidator, ColumnSchemaValidator, DatasourceConnectionConfigValidator, TableSchemaValidator, TableDataValidator, CredentialsValidator } from '../models/datasetCreateConfigValidator';
|
||||
import { QuickCreateValidator } from '../models/quickCreateValidator';
|
||||
import { PrintSettingsValidator } from '../models/printSettingsValidator';
|
||||
import { PaginatedReportDatasetBindingValidator } from '../models/paginatedReportDatasetBindingValidator';
|
||||
|
||||
export interface IValidationError {
|
||||
path?: string;
|
||||
|
@ -136,7 +139,7 @@ export const Validators = {
|
|||
filterConditionsValidator: new ArrayValidator([new ConditionItemValidator()]),
|
||||
filterHierarchyTargetValidator: new FilterHierarchyTargetValidator(),
|
||||
filterMeasureTargetValidator: new FilterMeasureTargetValidator(),
|
||||
filterTargetValidator: new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator()])])]),
|
||||
filterTargetValidator: new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator()])])])])]),
|
||||
filterValidator: new FilterValidator(),
|
||||
filterTypeValidator: new EnumValidator([0, 1, 2, 3, 4, 5, 6, 7, 9]),
|
||||
filtersArrayValidator: new ArrayValidator([new FilterValidator()]),
|
||||
|
@ -146,6 +149,7 @@ export const Validators = {
|
|||
hyperlinkClickBehaviorValidator: new EnumValidator([0, 1, 2]),
|
||||
includeExcludeFilterValidator: new IncludeExcludeFilterValidator(),
|
||||
includeExludeFilterTypeValidator: new EnumValidator([3]),
|
||||
includeExcludeFilterValuesValidator: new ArrayValidator([new AnyOfValidator([new StringValidator(), new NumberValidator(), new BooleanValidator(), new ArrayValidator([new ArrayValidator([new IncludeExcludePointValueValidator()])])])]),
|
||||
hierarchyFilterTypeValidator: new EnumValidator([9]),
|
||||
hierarchyFilterValuesValidator: new ArrayValidator([new HierarchyFilterNodeValidator()]),
|
||||
layoutTypeValidator: new EnumValidator([0, 1, 2, 3]),
|
||||
|
@ -168,12 +172,14 @@ export const Validators = {
|
|||
pageViewFieldValidator: new PageViewFieldValidator(),
|
||||
pagesLayoutValidator: new MapValidator([new StringValidator()], [new PageLayoutValidator()]),
|
||||
paginatedReportCommandsValidator: new PaginatedReportCommandsValidator(),
|
||||
paginatedReportDatasetBindingArrayValidator: new ArrayValidator([new PaginatedReportDatasetBindingValidator()]),
|
||||
paginatedReportLoadValidator: new PaginatedReportLoadValidator(),
|
||||
paginatedReportsettingsValidator: new PaginatedReportSettingsValidator(),
|
||||
parameterValuesArrayValidator: new ArrayValidator([new ReportParameterFieldsValidator()]),
|
||||
parametersPanelValidator: new ParametersPanelValidator(),
|
||||
permissionsValidator: new EnumValidator([0, 1, 2, 4, 7]),
|
||||
playBookmarkRequestValidator: new PlayBookmarkRequestValidator(),
|
||||
printSettingsValidator: new PrintSettingsValidator(),
|
||||
qnaInterpretInputDataValidator: new QnaInterpretInputDataValidator(),
|
||||
qnaPanesValidator: new QnaPanesValidator(),
|
||||
qnaSettingValidator: new QnaSettingsValidator(),
|
||||
|
|
|
@ -16,10 +16,22 @@ export class DatasetBindingValidator extends ObjectValidator {
|
|||
return errors;
|
||||
}
|
||||
|
||||
if (!input["datasetId"] && !input["paginatedReportBindings"]) {
|
||||
return [{
|
||||
message: "datasetBinding cannot be empty",
|
||||
path: (path ? path + "." : "") + field,
|
||||
keyword: "invalid"
|
||||
}];
|
||||
}
|
||||
|
||||
const fields: IFieldValidatorsPair[] = [
|
||||
{
|
||||
field: "datasetId",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
|
||||
validators: [Validators.stringValidator]
|
||||
},
|
||||
{
|
||||
field: "paginatedReportBindings",
|
||||
validators: [Validators.paginatedReportDatasetBindingArrayValidator]
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -430,7 +430,7 @@ export class IncludeExcludeFilterValidator extends FilterValidatorBase {
|
|||
},
|
||||
{
|
||||
field: "values",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.anyArrayValidator]
|
||||
validators: [Validators.fieldRequiredValidator, Validators.includeExcludeFilterValuesValidator]
|
||||
},
|
||||
{
|
||||
field: "filterType",
|
||||
|
@ -505,6 +505,33 @@ export class HierarchyFilterNodeValidator extends ObjectValidator {
|
|||
}
|
||||
}
|
||||
|
||||
export class IncludeExcludePointValueValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const errors = super.validate(input, path, field);
|
||||
if (errors) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const fields: IFieldValidatorsPair[] = [
|
||||
{
|
||||
field: "value",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.anyValueValidator]
|
||||
},
|
||||
{
|
||||
field: "keyValues",
|
||||
validators: [Validators.anyArrayValidator]
|
||||
}
|
||||
];
|
||||
|
||||
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
|
||||
return multipleFieldsValidator.validate(input, path, field);
|
||||
}
|
||||
}
|
||||
|
||||
export class FilterValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { IFieldValidatorsPair, MultipleFieldsValidator } from '../core/multipleFieldsValidator';
|
||||
import { ObjectValidator } from '../core/typeValidator';
|
||||
import { IValidationError, Validators } from '../core/validator';
|
||||
|
||||
export class PaginatedReportDatasetBindingValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const errors = super.validate(input, path, field);
|
||||
if (errors) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const fields: IFieldValidatorsPair[] = [
|
||||
{
|
||||
field: "sourceDatasetId",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
|
||||
},
|
||||
{
|
||||
field: "targetDatasetId",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
|
||||
}
|
||||
];
|
||||
|
||||
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
|
||||
return multipleFieldsValidator.validate(input, path, field);
|
||||
}
|
||||
}
|
|
@ -47,6 +47,10 @@ export class PaginatedReportLoadValidator extends ObjectValidator {
|
|||
{
|
||||
field: "parameterValues",
|
||||
validators: [Validators.parameterValuesArrayValidator]
|
||||
},
|
||||
{
|
||||
field: "datasetBindings",
|
||||
validators: [Validators.paginatedReportDatasetBindingArrayValidator]
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { IFieldValidatorsPair, MultipleFieldsValidator } from '../core/multipleFieldsValidator';
|
||||
import { EnumValidator, ObjectValidator } from '../core/typeValidator';
|
||||
import { IValidationError } from '../core/validator';
|
||||
|
||||
export class PrintSettingsValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const errors = super.validate(input, path, field);
|
||||
if (errors) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
const fields: IFieldValidatorsPair[] = [
|
||||
{
|
||||
field: "browserPrintAdjustmentsMode",
|
||||
validators: [new EnumValidator([0, 1])]
|
||||
}
|
||||
];
|
||||
|
||||
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
|
||||
return multipleFieldsValidator.validate(input, path, field);
|
||||
}
|
||||
}
|
|
@ -87,6 +87,10 @@ export class SettingsValidator extends ObjectValidator {
|
|||
{
|
||||
field: "authoringHintsEnabled",
|
||||
validators: [Validators.booleanValidator]
|
||||
},
|
||||
{
|
||||
field: "printSettings",
|
||||
validators: [Validators.printSettingsValidator]
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ describe('Unit | Models', () => {
|
|||
const accessTokenRequiredMessage = "accessToken is required";
|
||||
const accessTokenInvalidTypeMessage = "accessToken must be a string";
|
||||
const datasetIdInvalidTypeMessage = "datasetId must be a string";
|
||||
const datasetIdRequiredMessage = "datasetId is required";
|
||||
const idRequiredMessage = "id is required";
|
||||
const idInvalidTypeMessage = "id must be a string";
|
||||
const pageNameInvalidTypeMessage = "pageName must be a string";
|
||||
|
@ -266,7 +265,7 @@ describe('Unit | Models', () => {
|
|||
expect(errors).toBeUndefined();
|
||||
});
|
||||
|
||||
it(`should return errors with one containing message '${datasetIdRequiredMessage}' if datasetId doesn't exists`, () => {
|
||||
it(`should return errors if no datasetId nor PaginatedReportDatasetBindings is provided`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
load: {
|
||||
|
@ -276,11 +275,51 @@ describe('Unit | Models', () => {
|
|||
}
|
||||
}
|
||||
};
|
||||
// Act
|
||||
const errors = models.validateReportLoad(testData.load);
|
||||
// Assert
|
||||
testForExpectedMessage(errors, "datasetBinding cannot be empty");
|
||||
});
|
||||
|
||||
it(`should return undefined if id, accessToken are provided and paginatedReportBindings is valid`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
load: {
|
||||
id: 'fakeId',
|
||||
accessToken: 'fakeAccessToken',
|
||||
datasetBinding: {
|
||||
paginatedReportBindings: [
|
||||
{ sourceDatasetId: 'sourceDatasetId', targetDatasetId: 'targetDatasetId' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
const errors = models.validateReportLoad(testData.load);
|
||||
// Assert
|
||||
testForExpectedMessage(errors, datasetIdRequiredMessage);
|
||||
expect(errors).toBeUndefined();
|
||||
});
|
||||
|
||||
it(`should return undefined if id, accessToken are provided and both datasetBinding and paginatedReportBindings is valid`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
load: {
|
||||
id: 'fakeId',
|
||||
accessToken: 'fakeAccessToken',
|
||||
datasetBinding: {
|
||||
datasetId: "fakeDatasetId",
|
||||
paginatedReportBindings: [
|
||||
{ sourceDatasetId: 'sourceDatasetId', targetDatasetId: 'targetDatasetId' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
const errors = models.validateReportLoad(testData.load);
|
||||
// Assert
|
||||
expect(errors).toBeUndefined();
|
||||
});
|
||||
|
||||
it(`should return errors with one containing message '${datasetIdInvalidTypeMessage}' if datasetId is not a string`, () => {
|
||||
|
@ -651,10 +690,16 @@ describe('Unit | Models', () => {
|
|||
});
|
||||
|
||||
describe('validatePaginatedReportLoad', () => {
|
||||
const testData: any = {
|
||||
let testData: any = {
|
||||
accessToken: "token",
|
||||
id: "reportid",
|
||||
};
|
||||
beforeEach(() => {
|
||||
testData = {
|
||||
accessToken: "token",
|
||||
id: "reportid",
|
||||
};
|
||||
});
|
||||
it(`happy path`, () => {
|
||||
testData.settings = { commands: { parameterPanel: { enabled: true, expanded: true } } };
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
|
@ -698,6 +743,34 @@ describe('Unit | Models', () => {
|
|||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'parameterValues property is invalid');
|
||||
});
|
||||
it('should fail if datasetBindings are defined without sourceDatasetId', () => {
|
||||
testData.datasetBindings = [
|
||||
{
|
||||
targetDatasetId: 'targetDatasetId'
|
||||
}
|
||||
];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'datasetBindings property is invalid');
|
||||
});
|
||||
it('should fail if datasetBindings are defined without targetDatasetId', () => {
|
||||
testData.datasetBindings = [
|
||||
{
|
||||
sourceDatasetId: 'sourceDatasetId'
|
||||
}
|
||||
];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'datasetBindings property is invalid');
|
||||
});
|
||||
it('should fail if datasetBindings are defined with not string types', () => {
|
||||
testData.datasetBindings = [
|
||||
{
|
||||
sourceDatasetId: 2,
|
||||
targetDatasetId: null
|
||||
}
|
||||
];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'datasetBindings property is invalid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateDashboardLoad', () => {
|
||||
|
@ -1247,6 +1320,44 @@ describe('Unit | Models', () => {
|
|||
expect(models.validateFilter(filter.toJSON())).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return undefined if object is valid include/exclude filter schema with multiple targets", () => {
|
||||
// Arrange
|
||||
const expectedFilter: models.IIncludeExcludeFilter = {
|
||||
$schema: "http://powerbi.com/product/schema#includeExclude",
|
||||
target: [
|
||||
[{
|
||||
table: "a",
|
||||
column: "b"
|
||||
},
|
||||
{
|
||||
table: "a",
|
||||
column: "c"
|
||||
}]
|
||||
],
|
||||
values: [
|
||||
[
|
||||
[
|
||||
{value: 1}, {value: 2}
|
||||
],
|
||||
[
|
||||
{value: 3}, {value: 4}
|
||||
]
|
||||
]
|
||||
],
|
||||
isExclude: false,
|
||||
filterType: models.FilterType.IncludeExclude
|
||||
};
|
||||
|
||||
// Act
|
||||
const filter = new models.IncludeExcludeFilter(
|
||||
expectedFilter.target,
|
||||
expectedFilter.isExclude,
|
||||
expectedFilter.values);
|
||||
|
||||
// Assert
|
||||
expect(models.validateFilter(filter.toJSON())).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return undefined if object is valid advanced filter schema", () => {
|
||||
// Arrange
|
||||
const expectedFilter: models.IAdvancedFilter = {
|
||||
|
@ -1490,6 +1601,8 @@ describe('Unit | Models', () => {
|
|||
const layoutTypeInvalidTypeMessage = "layoutType must be a number";
|
||||
const layoutTypeInvalidMessage = "layoutType property is invalid";
|
||||
const customLayoutInvalidMessage = "customLayout must be an object";
|
||||
const browserPrintAdjustmentsModeInvalidMessage = "browserPrintAdjustmentsMode property is invalid";
|
||||
const printSettingsInvalidMessage = "printSettings must be an object";
|
||||
const hyperlinkClickBehaviorInvalidTypeMessage = "hyperlinkClickBehavior must be a number";
|
||||
const hyperlinkClickBehaviorInvalidMessage = "hyperlinkClickBehavior property is invalid";
|
||||
const modeInvalidMessage = "mode property is invalid";
|
||||
|
@ -1766,6 +1879,38 @@ describe('Unit | Models', () => {
|
|||
testForExpectedMessage(errors, modeInvalidMessage);
|
||||
});
|
||||
|
||||
it(`should return errors with one containing message '${printSettingsInvalidMessage}' if printSettings type is not valid`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
settings: {
|
||||
printSettings: 1
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
const errors = models.validateSettings(testData.settings);
|
||||
|
||||
// Assert
|
||||
testForExpectedMessage(errors, printSettingsInvalidMessage);
|
||||
});
|
||||
|
||||
it(`should return errors with one containing message '${browserPrintAdjustmentsModeInvalidMessage}' if browserPrintAdjustmentsMode value is not valid`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
settings: {
|
||||
printSettings: {
|
||||
browserPrintAdjustmentsMode: 2
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
const errors = models.validateSettings(testData.settings);
|
||||
|
||||
// Assert
|
||||
testForExpectedMessage(errors, browserPrintAdjustmentsModeInvalidMessage);
|
||||
});
|
||||
|
||||
it(`should return undefined if settings is valid (empty)`, () => {
|
||||
// Arrange
|
||||
const testData = {
|
||||
|
@ -1791,7 +1936,8 @@ describe('Unit | Models', () => {
|
|||
extensions: [{ command: { name: "name", extend: {}, title: "title" } }],
|
||||
commands: [{ exportData: { displayOption: models.CommandDisplayOption.Enabled } }],
|
||||
layoutType: 0,
|
||||
customLayout: {}
|
||||
customLayout: {},
|
||||
printSettings: { browserPrintAdjustmentsMode: 1 }
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3707,6 +3853,56 @@ describe("Unit | Filters", () => {
|
|||
// Assert
|
||||
expect(filter.toJSON()).toEqual(expectedFilter);
|
||||
});
|
||||
|
||||
it("should output the correct json when toJSON is called with multiple targets", () => {
|
||||
// Arrange
|
||||
const expectedFilter: models.IIncludeExcludeFilter = {
|
||||
$schema: "http://powerbi.com/product/schema#includeExclude",
|
||||
target: [
|
||||
[{
|
||||
table: "a",
|
||||
column: "b"
|
||||
},
|
||||
{
|
||||
table: "a",
|
||||
column: "c"
|
||||
}],
|
||||
[{
|
||||
table: "a",
|
||||
column: "d"
|
||||
}]
|
||||
],
|
||||
values: [
|
||||
[
|
||||
[
|
||||
{value: 1}, {value: 2}
|
||||
],
|
||||
[
|
||||
{value: 3}, {value: 4}
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
{value: 5}
|
||||
],
|
||||
[
|
||||
{value: 6}
|
||||
]
|
||||
]
|
||||
],
|
||||
isExclude: false,
|
||||
filterType: models.FilterType.IncludeExclude
|
||||
};
|
||||
|
||||
// Act
|
||||
const filter = new models.IncludeExcludeFilter(
|
||||
expectedFilter.target,
|
||||
expectedFilter.isExclude,
|
||||
expectedFilter.values);
|
||||
|
||||
// Assert
|
||||
expect(filter.toJSON()).toEqual(expectedFilter);
|
||||
});
|
||||
});
|
||||
|
||||
describe('determine types', () => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче