Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] [EDT-1091] Connector instance per image variable #347

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/controllers/ConnectorController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class ConnectorController {
};

/**
* Gets the current state a connector is in, to wait until a connector is ready to be used, use the 'waitForConnectorReady'
* Gets the current state a connector is in, to wait until a connector is ready to be used, use the 'waitToBeReady'
* method in this controller.
* @param id the id of your registered connector you want to make sure it is loaded
* @returns connector state
Expand Down
73 changes: 72 additions & 1 deletion src/controllers/UndoManagerController.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import SDK from '..';
import { EditorAPI } from '../types/CommonTypes';
import { getEditorResponseData } from '../utils/EditorResponseData';

Expand All @@ -10,12 +11,16 @@ export class UndoManagerController {
* @ignore
*/
#editorAPI: EditorAPI;
#advanced: AdvancedUndoManagerController;
#sdk: SDK;

/**
* @ignore
*/
constructor(children: EditorAPI) {
constructor(children: EditorAPI, sdk: SDK) {
this.#editorAPI = children;
this.#sdk = sdk;
this.#advanced = new AdvancedUndoManagerController(children);
}

/**
Expand All @@ -35,4 +40,70 @@ export class UndoManagerController {
const res = await this.#editorAPI;
return res.redo().then((result) => getEditorResponseData<null>(result));
};

/**
* Record any operations in the current scope. This will automatically begin
* the undo operation. Once you leave the record scope, it will end the undo operation.
* Even if you throw an exception inside the record scope it will still end it properly.
* @returns
*/
record = async (operationName: string, undoOperationCallback: (sdk: SDK) => void) => {
try {
await this.#advanced.begin(operationName);

await undoOperationCallback(this.#sdk);
} catch (error) {
throw error;
}
finally {
await this.#advanced.end();
}
};
}

export class AdvancedUndoManagerController {
/**
* @ignore
*/
#editorAPI: EditorAPI;

/**
* @ignore
*/
constructor(children: EditorAPI) {
this.#editorAPI = children;
}

/**
* This will start a new undo operation.
* This will throw an exception when there is already an undo operation recording.
* @returns
*/
begin = async (operationName: string) => {
const res = await this.#editorAPI;
return res.begin(operationName).then((result) => getEditorResponseData<null>(result));
};

/**
* This will start a new undo operation if there is no other undo operation recording.
* This does not throw.
* @returns
*/
beginIfNoneActive = async (operationName: string) => {
const res = await this.#editorAPI;
return res.beginIfNoneActive(operationName).then((result) => getEditorResponseData<null>(result));
};


/**
* Ends the currently active recording operation.
* If there is no recording operation currently running this will throw an exception.
* @returns
*/
end = async () => {
const res = await this.#editorAPI;
return res.end().then((result) => getEditorResponseData<null>(result));
};

}

12 changes: 8 additions & 4 deletions src/controllers/VariableController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EditorAPI, Id } from '../types/CommonTypes';
import { ConnectorRegistration } from '../types/ConnectorTypes';
import {
Variable,
VariableType,
Expand Down Expand Up @@ -63,7 +64,9 @@ export class VariableController {
};

/**
* This method removes a list of variables
* This method removes a list of variables.
*
* All connectors linked to the variables will be unregistered.
* @param ids list of the variables to be removed
* @returns
*/
Expand Down Expand Up @@ -228,13 +231,14 @@ export class VariableController {
/**
* This method sets the image variable connector. Setting a connector will
* automatically remove the assetId linked to the connector if present.
* If a connector was the source of the variable, it will be unregistered.
* @param id The ID of the image variable to update
* @param connectorId The new ID of the connector
* @param registration registration object containing all details about the connector
* @returns
*/
setImageVariableConnector = async (id: string, connectorId: string) => {
setImageVariableConnector = async (id: string, registration: ConnectorRegistration) => {
const res = await this.#editorAPI;
return res.setImageVariableConnector(id, connectorId).then((result) => getEditorResponseData<null>(result));
return res.setImageVariableConnector(id, JSON.stringify(registration)).then((result) => getEditorResponseData<Id>(result));
};

/**
Expand Down
6 changes: 3 additions & 3 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export class SDK {
this.layout = new LayoutController(this.editorAPI);
this.frame = new FrameController(this.editorAPI);
this.shape = new ShapeController(this.editorAPI);
this.undoManager = new UndoManagerController(this.editorAPI, this);
this.connector = new ConnectorController(this.editorAPI);
this.mediaConnector = new MediaConnectorController(this.editorAPI);
this.fontConnector = new FontConnectorController(this.editorAPI);
Expand All @@ -102,7 +103,6 @@ export class SDK {
this.tool = new ToolController(this.editorAPI);
this.page = new PageController(this.editorAPI);
this.debug = new DebugController(this.editorAPI);
this.undoManager = new UndoManagerController(this.editorAPI);
// To be renamed textSelection > textStyle
this.textSelection = new TextStyleController(this.editorAPI);
this.colorStyle = new ColorStyleController(this.editorAPI);
Expand Down Expand Up @@ -164,19 +164,19 @@ export class SDK {
this.animation = new AnimationController(this.editorAPI);
this.document = new DocumentController(this.editorAPI);
this.configuration = new ConfigurationController(this.editorAPI);
this.variable = new VariableController(this.editorAPI);
this.utils = new UtilsController();
this.tool = new ToolController(this.editorAPI);
this.page = new PageController(this.editorAPI);
this.debug = new DebugController(this.editorAPI);
this.undoManager = new UndoManagerController(this.editorAPI);
this.undoManager = new UndoManagerController(this.editorAPI, this);
this.textSelection = new TextStyleController(this.editorAPI);
this.colorStyle = new ColorStyleController(this.editorAPI);
this.paragraphStyle = new ParagraphStyleController(this.editorAPI);
this.characterStyle = new CharacterStyleController(this.editorAPI);
this.mediaConnector = new MediaConnectorController(this.editorAPI);
this.fontConnector = new FontConnectorController(this.editorAPI);
this.connector = new ConnectorController(this.editorAPI);
this.variable = new VariableController(this.editorAPI);
this.font = new FontController(this.editorAPI);
this.experiment = new ExperimentController(this.editorAPI);
this.canvas = new CanvasController(this.editorAPI);
Expand Down
4 changes: 2 additions & 2 deletions src/tests/controllers/ConnectorController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ConnectorMapping,
ConnectorMappingSource,
ConnectorMappingTarget,
ConnectorRegistration,
ConnectorRegistrationSource,
ConnectorType,
} from '../../types/ConnectorTypes';
Expand Down Expand Up @@ -40,8 +41,7 @@ afterEach(() => {
jest.restoreAllMocks();
});
describe('ConnectorController', () => {
const registration = {
id: '',
const registration: ConnectorRegistration = {
source: ConnectorRegistrationSource.url,
url: '',
};
Expand Down
46 changes: 44 additions & 2 deletions src/tests/controllers/UndoManagerController.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import { UndoManagerController } from '../../controllers/UndoManagerController';
import { AdvancedUndoManagerController, UndoManagerController } from '../../controllers/UndoManagerController';
// eslint-disable-next-line import/no-named-as-default
import SDK from '../../sdk';
import { EditorAPI } from '../../types/CommonTypes';
import { getEditorResponseData, castToEditorResponse } from '../../utils/EditorResponseData';
import mockConfig from '../__mocks__/config';

describe('UndoManagerController', () => {
let mockedUndoManagerController: UndoManagerController;
let mockedAdvancedUndoManagerController: AdvancedUndoManagerController;
const mockSDK = new SDK(mockConfig);

const mockEditorApi: EditorAPI = {
undo: async () => getEditorResponseData(castToEditorResponse(null)),
redo: async () => getEditorResponseData(castToEditorResponse(null)),
begin: async () => getEditorResponseData(castToEditorResponse(null)),
beginIfNoneActive: async () => getEditorResponseData(castToEditorResponse(null)),
end: async () => getEditorResponseData(castToEditorResponse(null)),
};


beforeEach(() => {
mockedUndoManagerController = new UndoManagerController(mockEditorApi);
mockedUndoManagerController = new UndoManagerController(mockEditorApi, mockSDK);
mockedAdvancedUndoManagerController = new AdvancedUndoManagerController(mockEditorApi);
jest.spyOn(mockEditorApi, 'undo');
jest.spyOn(mockEditorApi, 'redo');
jest.spyOn(mockEditorApi, 'begin');
jest.spyOn(mockEditorApi, 'beginIfNoneActive');
jest.spyOn(mockEditorApi, 'end');
});

afterEach(() => {
Expand All @@ -29,4 +42,33 @@ describe('UndoManagerController', () => {
await mockedUndoManagerController.redo();
expect(mockEditorApi.redo).toHaveBeenCalledTimes(1);
});

it('Records an operation', async () => {
let dummy = false;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
await mockedUndoManagerController.record('my undo operation', (_) => {
dummy = true;
});

expect(mockEditorApi.begin).toHaveBeenCalledTimes(1);
expect(dummy).toBe(true);
expect(mockEditorApi.end).toHaveBeenCalledTimes(1);
});

it('Begins an operation', async () => {
const operationName = 'operationName';

await mockedAdvancedUndoManagerController.begin(operationName);
expect(mockEditorApi.begin).toHaveBeenCalledTimes(1);
expect(mockEditorApi.begin).toHaveBeenCalledWith(operationName);
});

it('Begins an operation if none is active', async () => {
const operationName = 'operationName';

await mockedAdvancedUndoManagerController.beginIfNoneActive(operationName);
expect(mockEditorApi.beginIfNoneActive).toHaveBeenCalledTimes(1);
expect(mockEditorApi.beginIfNoneActive).toHaveBeenCalledWith(operationName);
});
});
37 changes: 31 additions & 6 deletions src/tests/controllers/VariableController.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { VariableController } from '../../controllers/VariableController';
import { VariableType } from '../../types/VariableTypes';
import { ImageVariable, VariableType } from '../../types/VariableTypes';
import { EditorAPI } from '../../types/CommonTypes';
import { getEditorResponseData, castToEditorResponse } from '../../utils/EditorResponseData';
import { ConnectorRegistration, ConnectorRegistrationSource } from '../../types/ConnectorTypes';

afterEach(() => {
jest.restoreAllMocks();
Expand All @@ -10,8 +11,26 @@ afterEach(() => {
describe('VariableController', () => {
let mockedVariableController: VariableController;

const connectorId = 'connectorId';
const variableId = 'variableId';

const variable: ImageVariable = {
id: variableId,
type: VariableType.image,
name: '',
label: '',
isVisible: true,
isReadonly: false,
isRequired: false,
occurrences: 0,
value: {
connectorId: connectorId,
assetId: 'assetId',
},
};

const mockEditorApi: EditorAPI = {
getVariableById: async () => getEditorResponseData(castToEditorResponse(null)),
getVariableById: async () => getEditorResponseData(castToEditorResponse(variable)),
getVariableByName: async () => getEditorResponseData(castToEditorResponse(null)),
getVariables: async () => getEditorResponseData(castToEditorResponse(null)),
addVariable: async () => getEditorResponseData(castToEditorResponse(null)),
Expand Down Expand Up @@ -55,8 +74,11 @@ describe('VariableController', () => {
jest.spyOn(mockEditorApi, 'setVariableName');
jest.spyOn(mockEditorApi, 'setVariableSource');
jest.spyOn(mockEditorApi, 'setImageVariableConnector');

});



it('get variable by id', async () => {
await mockedVariableController.getById('2');
expect(mockEditorApi.getVariableById).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -177,13 +199,16 @@ describe('VariableController', () => {
});

it('set image variable connector', async () => {
const varId = '1';
const connectorId = 'connectorId';
const registration: ConnectorRegistration = {
url: 'test://test.test',
source: ConnectorRegistrationSource.url
};

await mockedVariableController.setImageVariableConnector(varId, connectorId);
await mockedVariableController.setImageVariableConnector(variableId, registration);

expect(mockEditorApi.setImageVariableConnector).toHaveBeenCalledTimes(1);
expect(mockEditorApi.setImageVariableConnector).toHaveBeenCalledWith(varId, connectorId);
expect(mockEditorApi.setImageVariableConnector).toHaveBeenCalledWith(variableId, JSON.stringify(registration));

});

it('remove variable source', async () => {
Expand Down
Loading