Skip to content

Commit

Permalink
refactor(window): make more mockable
Browse files Browse the repository at this point in the history
  • Loading branch information
R0tenur committed Oct 21, 2023
1 parent 2b410ed commit 296469e
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 36 deletions.
9 changes: 9 additions & 0 deletions backend/src/message.handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@ describe("messageHandler", () => {
let getMssqlDbSchemaSpy;
let showErrorSpy;
let exportSpy;
let showResultSpy;
let chartBuilderSpy;

beforeEach(() => {
getMssqlDbSchemaSpy = spyOn(repository, "getMssqlDbSchema");
showErrorSpy = spyOn(messageFunction, "showError");
exportSpy = spyOn(exporter, "exportService");
showResultSpy = spyOn(messageFunction, "showResult");
chartBuilderSpy = spyOn(
require("./services/builder.service"),
"chartBuilder"
).and.returnValue("chart");
});

describe("load", () => {
Expand Down Expand Up @@ -58,6 +65,8 @@ describe("messageHandler", () => {
status: Status.BuildingChart,
databaseRaw: [],
});
expect(chartBuilderSpy).toHaveBeenCalledWith([]);
expect(showResultSpy).toHaveBeenCalledWith(view, "chart", { tables: [] });
});
});
describe("save", () => {
Expand Down
13 changes: 11 additions & 2 deletions frontend/src/app/app-testing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import { ButtonComponent } from './components/button/button.component';
import { MERMAID } from './services/mermaid.token';
import { WINDOW } from './services/window.token';
let list: (e: Event) => void;

const postMessageSpy = jasmine.createSpy('psotMessageSpy');

const fakeWindowProvider = {
provide: WINDOW,
useFactory: () => ({
useValue: {
removeEventListener: (type: string, listener: () => void) => {
list = undefined as any as (e: Event) => void;
},
Expand All @@ -29,7 +32,13 @@ const fakeWindowProvider = {
},
],
},
}),
acquireVsCodeApi: () => ({
postMessage: postMessageSpy,
}),
console: {
log: (message: any) => {},
},
},
};

const fakeMermaidProvider = {
Expand Down
69 changes: 53 additions & 16 deletions frontend/src/app/services/data-studio.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ import { AppTestingModule } from '../app-testing.module';
import { AlertService } from './alert.service';

import { DataStudioService } from './data-studio.service';
import { WINDOW } from './window.token';
import { WINDOW, WindowService } from './window.token';
import { Subscription } from 'rxjs';
import { MERMAID } from './mermaid.token';
import { Exportable } from '../models/exportable.model';

describe('DataStudioService', () => {
let dataStudioService: DataStudioService;
let alert: AlertService;
let windowRef: Window;
let windowRef: WindowService;
let mermaid: any;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [AppTestingModule],
});

alert = TestBed.inject(AlertService);
windowRef = TestBed.inject(WINDOW);
mermaid = TestBed.inject(MERMAID);
Expand All @@ -32,13 +33,7 @@ describe('DataStudioService', () => {
describe('isInDataStudio', () => {
it('should return false when not in data studio', () => {
// Arrange
spyOn(windowRef.document, 'getElementsByTagName')
.withArgs('body')
.and.returnValue([
{
hasAttribute: (attribute: string) => false,
},
] as any as HTMLCollectionOf<Element>);
fakeIsInDataStudio(false);

// Act
const isInDataStudio = dataStudioService.isInDataStudio();
Expand All @@ -49,13 +44,8 @@ describe('DataStudioService', () => {

it('should return true when in data studio', () => {
// Arrange
spyOn(windowRef.document, 'getElementsByTagName')
.withArgs('body')
.and.returnValue([
{
hasAttribute: (attribute: string) => true,
},
] as any as HTMLCollectionOf<Element>);

fakeIsInDataStudio(true);

// Act
const isInDataStudio = dataStudioService.isInDataStudio();
Expand Down Expand Up @@ -184,6 +174,43 @@ describe('DataStudioService', () => {
}));
});

describe('postMessage', () => {
it('should trigger save command when exportSvg', () => {
// Arrange
spyOn(windowRef.console, 'log');
const svg = 'dummySvg';
const mermaid = 'dummyMermaid';

// Act
dataStudioService.saveCommand({ mermaid, svg });

// Assert
expect(windowRef.console.log).toHaveBeenCalledWith('posted', {
command: 'save',
data: { mermaid, svg },
});
});

it('should trigger load command when load', () => {
// Arrange
spyOn(windowRef.console, 'log');

const options = {
showViews: true,
showTables: true,
};

// Act
dataStudioService.loadCommand(options);

// Assert
expect(windowRef.console.log).toHaveBeenCalledWith('posted', {
command: 'load',
options,
});
});
});

const createEvent = (data: any) => {
const event = new CustomEvent('message') as any;
event.data = data;
Expand All @@ -203,4 +230,14 @@ describe('DataStudioService', () => {

return fakeCallback;
};

const fakeIsInDataStudio = (returns: boolean) => {
spyOn(windowRef.document, 'getElementsByTagName')
.withArgs('body')
.and.returnValue([
{
hasAttribute: (attribute: string) => returns,
},
] as any as HTMLCollectionOf<Element>);
};
});
24 changes: 9 additions & 15 deletions frontend/src/app/services/data-studio.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import { filter, map, switchMap, tap } from 'rxjs/operators';
import { Status } from '../../../../shared/models/status.enum';
import { AlertService } from './alert.service';
import { Exportable } from '../models/exportable.model';
import { WINDOW } from './window.token';
import { WINDOW, WindowService } from './window.token';
import { MERMAID } from './mermaid.token';
import { ViewOptions } from '@shared/models/options.model';
declare const acquireVsCodeApi: () => {
postMessage: (message: any) => void;
};

interface AzData {
chart: string;
Expand Down Expand Up @@ -48,13 +45,14 @@ export class DataStudioService {
private readonly markdown$ = new ReplaySubject<string>();
private readonly db$ = new ReplaySubject<Exportable>();
private readonly vscode = this.isInDataStudio()
? acquireVsCodeApi()
? this.window.acquireVsCodeApi()
: {
postMessage: (message: any) => console.log('posted', message),
postMessage: (message: any) =>
this.window.console.log('posted', message),
};
private readonly clientStatus$ = new Subject<string>();
constructor(
@Inject(WINDOW) private readonly window: Window,
@Inject(WINDOW) private readonly window: WindowService,
@Inject(MERMAID) private readonly mermaid: any,
private readonly alert: AlertService
) {
Expand Down Expand Up @@ -104,19 +102,15 @@ export class DataStudioService {

public saveCommand(message: any): void {
this.vscode.postMessage({
...{
command: 'save',
data: message,
},
command: 'save',
data: message,
});
}

public loadCommand(options: ViewOptions): void {
this.vscode.postMessage({
...{
command: 'load',
options,
},
command: 'load',
options,
});
this.db$.next();
}
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/app/services/window.token.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
/* istanbul ignore file */
import { InjectionToken } from '@angular/core';

export const WINDOW = new InjectionToken<Window>('Window', {
export interface WindowService extends Window {
console: Console;
acquireVsCodeApi(): {
postMessage: (message: any) => void;
};
}

export const WINDOW = new InjectionToken<WindowService>('Window', {
providedIn: 'root',
factory(): Window {
return window;
factory(): WindowService {
return window as unknown as WindowService;
},
});

0 comments on commit 296469e

Please sign in to comment.