Skip to content
Closed
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
98 changes: 98 additions & 0 deletions src/utils/IterableActionRunner.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { IterableActionRunner } from './IterableActionRunner';
import { IterableConfig } from './IterableConfig';
import { IterableActionSource } from '../embedded/types';

describe('IterableActionRunner', () => {
const openAction = { type: 'openUrl', data: 'https://example.com' };

beforeEach(() => {
IterableConfig.urlHandler = null;
IterableConfig.customActionHandler = null;
IterableConfig.openLinksInNewTab = true;
jest.restoreAllMocks();
});

it('should return false when action is null', () => {
const result = IterableActionRunner.executeAction(
null,
null,
IterableActionSource.EMBEDDED
);
expect(result).toBe(false);
});

it('should open URL in new tab by default', () => {
const openSpy = jest.spyOn(window, 'open').mockImplementation();

IterableActionRunner.executeAction(
null,
openAction,
IterableActionSource.EMBEDDED
);

expect(openSpy).toHaveBeenCalledWith('https://example.com', '_blank');
});

it('should open URL in same tab when openLinksInNewTab is false', () => {
IterableConfig.openLinksInNewTab = false;
const assignMock = jest.fn();
Object.defineProperty(window, 'location', {
value: { assign: assignMock },
writable: true
});

IterableActionRunner.executeAction(
null,
openAction,
IterableActionSource.EMBEDDED
);

expect(assignMock).toHaveBeenCalledWith('https://example.com');
});

it('should use urlHandler when configured', () => {
const handleIterableURL = jest.fn().mockReturnValue(true);
IterableConfig.urlHandler = { handleIterableURL };

const result = IterableActionRunner.executeAction(
null,
openAction,
IterableActionSource.EMBEDDED
);

expect(result).toBe(true);
expect(handleIterableURL).toHaveBeenCalledWith(
'https://example.com',
expect.objectContaining({ action: openAction })
);
});

it('should fall back to default open when urlHandler returns false', () => {
const handleIterableURL = jest.fn().mockReturnValue(false);
IterableConfig.urlHandler = { handleIterableURL };
const openSpy = jest.spyOn(window, 'open').mockImplementation();

IterableActionRunner.executeAction(
null,
openAction,
IterableActionSource.EMBEDDED
);

expect(openSpy).toHaveBeenCalledWith('https://example.com', '_blank');
});

it('should call customActionHandler for non-URL actions', () => {
const handleIterableCustomAction = jest.fn().mockReturnValue(true);
IterableConfig.customActionHandler = { handleIterableCustomAction };

const customAction = { type: 'customType', data: 'someData' };
const result = IterableActionRunner.executeAction(
null,
customAction,
IterableActionSource.EMBEDDED
);

expect(result).toBe(true);
expect(handleIterableCustomAction).toHaveBeenCalled();
});
});
6 changes: 5 additions & 1 deletion src/utils/IterableActionRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ class IterableActionRunnerImpl {
}
}

window.open(uri, '_blank');
if (IterableConfig.openLinksInNewTab) {
window.open(uri, '_blank');
} else {
window.location.assign(uri);
}

return true;
}
Expand Down
7 changes: 7 additions & 0 deletions src/utils/IterableConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ export class IterableConfig {
public static urlHandler: IterableUrlHandler | null = null;

public static customActionHandler: IterableCustomActionHandler | null = null;

/**
* Controls whether URLs are opened in a new tab/window or the same tab.
* When true (default), URLs open in a new tab via window.open(url, '_blank').
* When false, URLs open in the same tab via window.location.assign(url).
*/
public static openLinksInNewTab = true;
}
Loading