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

INT-3298: Updated tests to BDD style #390

Merged
merged 23 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d7227dd
INT-3298: Added TestHooks.ts
danoaky-tiny Jun 12, 2024
eb1c96c
INT-3298: Added TestHelpers.ts
danoaky-tiny Jun 13, 2024
b41fc67
INT-3298: support for using minitature to specify tinymce version
danoaky-tiny Jun 13, 2024
05a2fde
INT-3298: Migrated LoadTinyTest to BDD style
danoaky-tiny Jun 13, 2024
fd76048
INT-3298: throwTimeout message param is now optional
danoaky-tiny Jun 13, 2024
82c9b05
INT-3298: Migrated NgZoneTest.ts to BDD style
danoaky-tiny Jun 13, 2024
b3f3886
INT-3298: Initial migration changes to NgModelTest.ts
danoaky-tiny Jun 13, 2024
4261de6
INT-3298: Added a *Test.ts eslint override
danoaky-tiny Jun 13, 2024
3e5051e
INT-3298: Refactored EditorFixture to extend ComponentFixture
danoaky-tiny Jun 13, 2024
c14538d
INT-3298: Increased skin load timeout
danoaky-tiny Jun 13, 2024
c69ed6c
INT-3298: loadedEditor$ is reset in now reset in a beforeEach
danoaky-tiny Jun 13, 2024
4da65bb
INT-3298: Removed old tests in NgModelTest.ts
danoaky-tiny Jun 13, 2024
a7aae9c
INT-3298: Enabled `destroyAfterEach` teardown option
danoaky-tiny Jun 14, 2024
deb3b05
INT-3298: Refactored TestHooks.ts to account for teardown option bein…
danoaky-tiny Jun 14, 2024
5cbf500
INT-3298: Refactored migrated tests to new TestHooks.ts changes
danoaky-tiny Jun 14, 2024
8b664e6
INT-3298: Refactor to use `eachVersionContext`
danoaky-tiny Jun 14, 2024
217b10c
INT-3298: `editorHook` can now be used with a single standalone compo…
danoaky-tiny Jun 14, 2024
f6f7147
INT-3298: Migrated EventBlacklistingTest.ts to BDD style
danoaky-tiny Jun 14, 2024
5425872
INT-3298: Added **/test/ts/**/*.ts to test eslint override
danoaky-tiny Jun 20, 2024
1ddf489
INT-3298: Moved fakeType to TestHelpers.ts
danoaky-tiny Jun 20, 2024
926dc87
INT-3298: Added FormGroup test with default and onpush change detection
danoaky-tiny Jun 20, 2024
6ca801c
INT-3299: Fixed id prop logging a warning when it shouldn't (#392)
danoaky-tiny Jul 8, 2024
464afb1
INT-3298: Added a changelog entry
danoaky-tiny Jul 8, 2024
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
18 changes: 18 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@
"quotes": [ "error", "single" ],
"semi": "error"
}
},
{
"files": [
"**/*Test.ts",
"**/test/**/*.ts"
],
"plugins": [
"chai-friendly"
],
"extends": [
"plugin:chai-friendly/recommended"
],
"rules": {
"no-unused-expressions": "off",
"no-console": "off",
"max-classes-per-file": "off",
"@typescript-eslint/no-non-null-assertion": "off"
}
}
],
"extends": [
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- Added rxjs ^7.4.0 as a peer dependency. Since last major release now uses rxjs v7 imports. #INT-3306
- `id` prop no longer logs a console warning on any use. #INT-3299

## 8.0.0 - 2024-04-29

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@
"@tinymce/beehive-flow": "^0.19.0",
"@tinymce/eslint-plugin": "^2.3.1",
"@tinymce/miniature": "^6.0.0",
"@types/chai": "^4.3.16",
"@types/node": "^20.11.30",
"autoprefixer": "^10.4.19",
"babel-loader": "^9.1.3",
"chai": "^5.1.1",
"codelyzer": "^6.0.2",
"copyfiles": "^2.4.1",
"core-js": "^3.36.1",
"eslint-plugin-chai-friendly": "^1.0.0",
"eslint-plugin-storybook": "^0.8.0",
"gh-pages": "^6.1.0",
"json": "11.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
const tagName = typeof this.tagName === 'string' ? this.tagName : 'div';
this._element = document.createElement(this.inline ? tagName : 'textarea');
if (this._element) {
if (document.getElementById(this.id)) {
const existingElement = document.getElementById(this.id);
if (existingElement && existingElement !== this._elementRef.nativeElement) {
/* eslint no-console: ["error", { allow: ["warn"] }] */
console.warn(`TinyMCE-Angular: an element with id [${this.id}] already exists. Editors with duplicate Id will not be able to mount`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ import 'zone.js/plugins/fake-async-test';
import { TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';

TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
teardown: { destroyAfterEach: true },
});
60 changes: 60 additions & 0 deletions tinymce-angular-component/src/test/ts/alien/TestHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Fun, Global, Arr, Strings } from '@ephox/katamari';
import { Observable, throwError, timeout } from 'rxjs';
import { ScriptLoader } from '../../../main/ts/utils/ScriptLoader';
import { Attribute, Remove, SelectorFilter, SugarElement } from '@ephox/sugar';
import { ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { EditorComponent } from '../../../main/ts/editor/editor.component';
import { Editor } from 'tinymce';
import { Keyboard, Keys } from '@ephox/agar';

export const apiKey = Fun.constant('qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc');

export const throwTimeout =
(timeoutMs: number, message: string = `Timeout ${timeoutMs}ms`) =>
<T>(source: Observable<T>) =>
source.pipe(
timeout({
first: timeoutMs,
with: () => throwError(() => new Error(message)),
})
);

export const deleteTinymce = () => {
ScriptLoader.reinitialize();

delete Global.tinymce;
delete Global.tinyMCE;

const hasTinyUri = (attrName: string) => (elm: SugarElement<Element>) =>
Attribute.getOpt(elm, attrName).exists((src) => Strings.contains(src, 'tinymce'));

const elements = Arr.flatten([
Arr.filter(SelectorFilter.all('script'), hasTinyUri('src')),
Arr.filter(SelectorFilter.all('link'), hasTinyUri('href')),
]);

Arr.each(elements, Remove.remove);
};

export const captureLogs = async (
method: 'log' | 'warn' | 'debug' | 'error',
fn: () => Promise<void> | void
): Promise<unknown[][]> => {
const original = console[method];
try {
const logs: unknown[][] = [];
console[method] = (...args: unknown[]) => logs.push(args);
await fn();
return logs;
} finally {
console[method] = original;
}
};

export const fakeTypeInEditor = (fixture: ComponentFixture<unknown>, str: string) => {
const editor: Editor = fixture.debugElement.query(By.directive(EditorComponent)).componentInstance.editor!;
editor.getBody().innerHTML = '<p>' + str + '</p>';
Keyboard.keystroke(Keys.space(), {}, SugarElement.fromDom(editor.getBody()));
fixture.detectChanges();
};
105 changes: 105 additions & 0 deletions tinymce-angular-component/src/test/ts/alien/TestHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { after, before, beforeEach, context } from '@ephox/bedrock-client';
import { ComponentFixture, TestBed, TestModuleMetadata } from '@angular/core/testing';
import { Type } from '@angular/core';
import { EditorComponent, Version } from '../../../main/ts/editor/editor.component';
import { firstValueFrom, map, switchMap, tap } from 'rxjs';
import { By } from '@angular/platform-browser';
import { Optional, Singleton } from '@ephox/katamari';
import { VersionLoader } from '@tinymce/miniature';
import { deleteTinymce, throwTimeout } from './TestHelpers';
import { FormsModule, ReactiveFormsModule, NgModel } from '@angular/forms';
import { Editor } from 'tinymce';

export const fixtureHook = <T = unknown>(component: Type<T>, moduleDef: TestModuleMetadata) => {
before(async () => {
await TestBed.configureTestingModule(moduleDef).compileComponents();
});

return () => TestBed.createComponent(component);
};

export const tinymceVersionHook = (version: Version) => {
before(async () => {
await VersionLoader.pLoadVersion(version);
});
after(() => {
deleteTinymce();
});
};

export interface EditorFixture<T> extends ComponentFixture<T> {
editorComponent: EditorComponent;
editor: Editor;
ngModel: Optional<NgModel>;
}

export type CreateEditorFixture<T> = (
props?: Partial<
Omit<
EditorComponent,
`${'on' | 'ng' | 'register' | 'set' | 'write'}${string}` | 'createElement' | 'initialise' | 'editor'
>
>
) => Promise<EditorFixture<T>>;

export const editorHook = <T = unknown>(component: Type<T>, moduleDef: TestModuleMetadata = {
imports: [ component, EditorComponent, FormsModule, ReactiveFormsModule ],
}): CreateEditorFixture<T> => {
const createFixture = fixtureHook(component, moduleDef);
const editorFixture = Singleton.value<EditorFixture<T>>();
beforeEach(() => editorFixture.clear());

return async (props = {}) => {
if (editorFixture.isSet()) {
return editorFixture.get().getOrDie();
}

const fixture = createFixture();
const editorComponent =
fixture.componentInstance instanceof EditorComponent
? fixture.componentInstance
: Optional.from(fixture.debugElement.query(By.directive(EditorComponent)))
.map((v): EditorComponent => v.componentInstance)
.getOrDie('EditorComponent instance not found');

for (const [ key, value ] of Object.entries(props)) {
(editorComponent as any)[key] = value;
}

fixture.detectChanges();

return firstValueFrom(
editorComponent.onInit.pipe(
throwTimeout(10000, `Timed out waiting for editor to load`),
switchMap(
({ editor }) =>
new Promise<Editor>((resolve) => {
if (editor.initialized) {
resolve(editor);
}
editor.once('SkinLoaded', () => resolve(editor));
})
),
map(
(editor): EditorFixture<T> =>
Object.assign(fixture, {
editorComponent,
editor,
ngModel: Optional.from(fixture.debugElement.query(By.directive(EditorComponent))).bind((debugEl) =>
Optional.from(debugEl.injector.get<NgModel>(NgModel, undefined, { optional: true }))
),
})
),
tap(editorFixture.set)
)
);
};
};

export const eachVersionContext = (versions: Version[], fn: (version: Version) => void) =>
versions.forEach((version) =>
context(`With version ${version}`, () => {
tinymceVersionHook(version);
fn(version);
})
);
75 changes: 0 additions & 75 deletions tinymce-angular-component/src/test/ts/alien/TestStore.ts

This file was deleted.

Loading
Loading