diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index b2a08ea0..6c0c9cf4 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -26,6 +26,7 @@ import { LoginService } from "./auth/login/login.service"; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { NotificationIndicatorComponent } from "./components/notification-indicator/notification-indicator.component"; import { AngularSvgIconModule, SvgIconRegistryService } from "angular-svg-icon"; +import { MatIconModule } from "@angular/material/icon"; describe("AppComponent", () => { let component: AppComponent; @@ -46,6 +47,7 @@ describe("AppComponent", () => { FormsModule, HttpClientTestingModule, RouterModule, + MatIconModule, AngularSvgIconModule.forRoot(), ], declarations: [ diff --git a/src/app/components/app-header/app-header.component.spec.ts b/src/app/components/app-header/app-header.component.spec.ts index 35f18dec..6da30828 100644 --- a/src/app/components/app-header/app-header.component.spec.ts +++ b/src/app/components/app-header/app-header.component.spec.ts @@ -31,6 +31,7 @@ import { AngularSvgIconModule } from "angular-svg-icon"; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { LoginMethod } from "src/app/app-config.model"; +import { MatIconModule } from "@angular/material/icon"; describe("AppHeaderComponent", () => { let component: AppHeaderComponent; @@ -55,6 +56,7 @@ describe("AppHeaderComponent", () => { AngularSvgIconModule.forRoot(), HttpClientTestingModule, RouterModule, + MatIconModule, ], declarations: [AppHeaderComponent, NotificationIndicatorComponent], providers: [ diff --git a/src/app/dataset-view/additional-components/data-component/data.component.spec.ts b/src/app/dataset-view/additional-components/data-component/data.component.spec.ts index 2db35aca..db2674a3 100644 --- a/src/app/dataset-view/additional-components/data-component/data.component.spec.ts +++ b/src/app/dataset-view/additional-components/data-component/data.component.spec.ts @@ -5,19 +5,9 @@ import { MatIconModule } from "@angular/material/icon"; import { MatMenuModule } from "@angular/material/menu"; import { DataComponent } from "./data.component"; -import { - emitClickOnElementByDataTestId, - findElementByDataTestId, - getElementByDataTestId, -} from "src/app/common/base-test.helpers.spec"; +import { emitClickOnElementByDataTestId, findElementByDataTestId } from "src/app/common/base-test.helpers.spec"; import { DatasetSubscriptionsService } from "../../dataset.subscriptions.service"; -import { - mockDataUpdate, - mockMetadataDerivedUpdate, - mockOverviewDataUpdate, - mockOverviewDataUpdateNullable, - mockSqlErrorUpdate, -} from "../data-tabs.mock"; +import { mockMetadataDerivedUpdate, mockOverviewDataUpdate, mockOverviewDataUpdateNullable } from "../data-tabs.mock"; import { RouterTestingModule } from "@angular/router/testing"; import { Location } from "@angular/common"; import { FormsModule } from "@angular/forms"; @@ -33,16 +23,9 @@ import { SqlEditorComponent } from "src/app/shared/editor/components/sql-editor/ import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; import { HttpClientModule } from "@angular/common/http"; import { Apollo } from "apollo-angular"; -import { ToastrModule, ToastrService } from "ngx-toastr"; -import { Clipboard } from "@angular/cdk/clipboard"; -import { QueryExplainerService } from "src/app/query-explainer/query-explainer.service"; -import { of } from "rxjs"; -import { mockQueryExplainerResponse } from "src/app/query-explainer/query-explainer.mocks"; -import { FileUploadService } from "src/app/services/file-upload.service"; -import { mockUploadPrepareResponse } from "src/app/api/mock/upload-file.mock"; +import { ToastrModule } from "ngx-toastr"; import { SavedQueriesSectionComponent } from "./saved-queries-section/saved-queries-section.component"; import { QueryAndResultSectionsComponent } from "./query-and-result-sections/query-and-result-sections.component"; -import { DatasetModule } from "../../dataset.module"; describe("DataComponent", () => { let component: DataComponent; @@ -50,10 +33,6 @@ describe("DataComponent", () => { let datasetSubsService: DatasetSubscriptionsService; let location: Location; let ngbModalService: NgbModal; - let clipboard: Clipboard; - let toastrService: ToastrService; - let queryExplainerService: QueryExplainerService; - let fileUploadService: FileUploadService; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -71,7 +50,6 @@ describe("DataComponent", () => { CdkAccordionModule, HttpClientModule, ToastrModule.forRoot(), - //DatasetModule, ], declarations: [ DataComponent, @@ -86,38 +64,17 @@ describe("DataComponent", () => { datasetSubsService = TestBed.inject(DatasetSubscriptionsService); location = TestBed.inject(Location); ngbModalService = TestBed.inject(NgbModal); - clipboard = TestBed.inject(Clipboard); - toastrService = TestBed.inject(ToastrService); component = fixture.componentInstance; component.datasetBasics = mockDatasetBasicsDerivedFragment; component.sqlLoading = false; component.sqlRequestCode = ""; spyOn(location, "getState").and.returnValue({ start: 0, end: 100 }); - datasetSubsService.emitSqlQueryDataChanged(mockDataUpdate); - queryExplainerService = TestBed.inject(QueryExplainerService); - fileUploadService = TestBed.inject(FileUploadService); }); it("should create", () => { expect(component).toBeTruthy(); }); - // it("should check that the progress bar for the editor disappears", fakeAsync(() => { - // fixture.detectChanges(); - - // expect(component.editorLoaded).toBeFalse(); - // const progressBarElementBefore = findElementByDataTestId(fixture, "editor-progress-bar"); - // expect(progressBarElementBefore).toBeDefined(); - - // component.editorLoaded = true; - // tick(); - // fixture.detectChanges(); - - // const progressBarElementAfter = findElementByDataTestId(fixture, "editor-progress-bar"); - // expect(progressBarElementAfter).toBeUndefined(); - // flush(); - // })); - it("should check run sql button", fakeAsync(() => { const runSQLRequestEmitSpy = spyOn(component.runSQLRequestEmit, "emit"); tick(); @@ -130,57 +87,6 @@ describe("DataComponent", () => { flush(); })); - // it("should check #ngOninit", () => { - // expect(component.currentData).toEqual([]); - // component.ngOnInit(); - // expect(component.sqlRequestCode).toEqual( - // `select\n *\nfrom '${mockDatasetBasicsDerivedFragment.alias}'\nwhere offset>=0 and offset<=100\norder by offset desc`, - // ); - // }); - - // it("should check successful query result update", fakeAsync(() => { - // tick(); - // fixture.detectChanges(); - // expect(component.currentData).toEqual(mockDataUpdate.content); - // flush(); - // })); - - // it("should check invalid SQL result update", fakeAsync(() => { - // tick(); - // fixture.detectChanges(); - // datasetSubsService.emitSqlErrorOccurred(mockSqlErrorUpdate); - // tick(); - // fixture.detectChanges(); - // const runSqlButton = findElementByDataTestId(fixture, "runSqlQueryButton") as HTMLButtonElement; - // const elem = getElementByDataTestId(fixture, "sql-error-message"); - // expect(runSqlButton.disabled).toBe(false); - // expect(elem.textContent).toEqual(mockSqlErrorUpdate.error); - // flush(); - // })); - - // it("should calculate sql request params", () => { - // datasetSubsService.emitSqlQueryDataChanged(mockDataUpdate); - // fixture.detectChanges(); - - // const sqlReq = spyOn(component.runSQLRequestEmit, "emit"); - // const limit = 1; - // const params = { - // query: component.sqlRequestCode, - // skip: component.currentData.length, - // limit: limit, - // }; - - // component.loadMore(limit); - // datasetSubsService.emitSqlQueryDataChanged(mockDataUpdate); - // expect(sqlReq).toHaveBeenCalledWith(params); - - // component.loadMore(limit); - // params.skip = component.currentData.length; - - // const secondCallParams = sqlReq.calls.allArgs()[1]; - // expect(secondCallParams).toEqual([params]); - // }); - it("should check schema column names", fakeAsync(() => { datasetSubsService.emitOverviewChanged({ schema: mockMetadataDerivedUpdate.schema, @@ -211,36 +117,4 @@ describe("DataComponent", () => { } as OverviewUpdate); expect(ngbModalServiceSpy).toHaveBeenCalledTimes(1); }); - - // it("should check click on `Share query` button", fakeAsync(() => { - // const toastServiceSpy = spyOn(toastrService, "success"); - // const clipboardCopySpy = spyOn(clipboard, "copy"); - // tick(); - // fixture.detectChanges(); - - // emitClickOnElementByDataTestId(fixture, "shareSqlQueryButton"); - // expect(toastServiceSpy).toHaveBeenCalledWith("Copied url to clipboard"); - // expect(clipboardCopySpy).toHaveBeenCalledTimes(1); - // flush(); - // })); - - // it("should check click on `Copy as curl command` button", () => { - // const toastServiceSpy = spyOn(toastrService, "success"); - // const clipboardCopySpy = spyOn(clipboard, "copy"); - // component.copyCurlCommand(); - // expect(toastServiceSpy).toHaveBeenCalledWith("Copied command to clipboard"); - // expect(clipboardCopySpy).toHaveBeenCalledTimes(1); - // }); - - // it("should check click on `Verify query result` button", () => { - // const processQuerySpy = spyOn(queryExplainerService, "processQueryWithProof").and.returnValue( - // of(mockQueryExplainerResponse), - // ); - // const uploadFilePrepareSpy = spyOn(fileUploadService, "uploadFilePrepare").and.returnValue( - // of(mockUploadPrepareResponse), - // ); - // component.verifyQueryResult(); - // expect(processQuerySpy).toHaveBeenCalledTimes(1); - // expect(uploadFilePrepareSpy).toHaveBeenCalledTimes(1); - // }); }); diff --git a/src/app/dataset-view/additional-components/data-component/data.component.ts b/src/app/dataset-view/additional-components/data-component/data.component.ts index e5a051f8..45628e48 100644 --- a/src/app/dataset-view/additional-components/data-component/data.component.ts +++ b/src/app/dataset-view/additional-components/data-component/data.component.ts @@ -1,9 +1,9 @@ import { ChangeDetectionStrategy, Component, EventEmitter, inject, Input, OnInit, Output } from "@angular/core"; import { Location } from "@angular/common"; -import { map, Observable } from "rxjs"; +import { Observable } from "rxjs"; import AppValues from "src/app/common/app.values"; import { DatasetFlowType, DatasetKind, OffsetInterval } from "../../../api/kamu.graphql.interface"; -import { DataSqlErrorUpdate, OverviewUpdate } from "src/app/dataset-view/dataset.subscriptions.interface"; +import { OverviewUpdate } from "src/app/dataset-view/dataset.subscriptions.interface"; import { DatasetRequestBySql } from "../../../interface/dataset.interface"; import { DatasetSubscriptionsService } from "../../dataset.subscriptions.service"; import { BaseComponent } from "src/app/common/base.component"; @@ -46,10 +46,10 @@ export class DataComponent extends BaseComponent implements OnInit { public ngOnInit(): void { this.overviewUpdate$ = this.datasetSubsService.overviewChanges; - this.sqlErrorMarker$ = this.sqlQueryService.sqlErrorOccurrences.pipe( - map((data: DataSqlErrorUpdate) => data.error), - ); - this.sqlQueryResponse$ = this.sqlQueryService.sqlQueryResponseChanges; + // this.sqlErrorMarker$ = this.sqlQueryService.sqlErrorOccurrences.pipe( + // map((data: DataSqlErrorUpdate) => data.error), + // ); + // this.sqlQueryResponse$ = this.sqlQueryService.sqlQueryResponseChanges; this.buildSqlRequestCode(); this.runSQLRequest({ query: this.sqlRequestCode }); } diff --git a/src/app/dataset-view/additional-components/data-component/query-and-result-sections/query-and-result-sections.component.spec.ts b/src/app/dataset-view/additional-components/data-component/query-and-result-sections/query-and-result-sections.component.spec.ts index 022b74f4..268bb669 100644 --- a/src/app/dataset-view/additional-components/data-component/query-and-result-sections/query-and-result-sections.component.spec.ts +++ b/src/app/dataset-view/additional-components/data-component/query-and-result-sections/query-and-result-sections.component.spec.ts @@ -1,10 +1,9 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, fakeAsync, flush, TestBed, tick } from "@angular/core/testing"; import { QueryAndResultSectionsComponent } from "./query-and-result-sections.component"; import { CdkAccordionModule } from "@angular/cdk/accordion"; -import { ActivatedRoute } from "@angular/router"; import { Apollo } from "apollo-angular"; import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { ToastrModule } from "ngx-toastr"; +import { ToastrModule, ToastrService } from "ngx-toastr"; import { MatMenuModule } from "@angular/material/menu"; import { RequestTimerComponent } from "../request-timer/request-timer.component"; import { SqlEditorComponent } from "src/app/shared/editor/components/sql-editor/sql-editor.component"; @@ -12,10 +11,26 @@ import { EditorModule } from "src/app/shared/editor/editor.module"; import { MatProgressBarModule } from "@angular/material/progress-bar"; import { MatIconModule } from "@angular/material/icon"; import { SharedTestModule } from "src/app/common/shared-test.module"; +import { + emitClickOnElementByDataTestId, + findElementByDataTestId, + getElementByDataTestId, +} from "src/app/common/base-test.helpers.spec"; +import { mockSqlErrorUpdate } from "../../data-tabs.mock"; +import { Clipboard } from "@angular/cdk/clipboard"; +import { QueryExplainerService } from "src/app/query-explainer/query-explainer.service"; +import { of } from "rxjs"; +import { mockUploadPrepareResponse } from "src/app/api/mock/upload-file.mock"; +import { mockQueryExplainerResponse } from "src/app/query-explainer/query-explainer.mocks"; +import { FileUploadService } from "src/app/services/file-upload.service"; describe("QueryAndResultSectionsComponent", () => { let component: QueryAndResultSectionsComponent; let fixture: ComponentFixture; + let clipboard: Clipboard; + let toastrService: ToastrService; + let queryExplainerService: QueryExplainerService; + let fileUploadService: FileUploadService; beforeEach(() => { TestBed.configureTestingModule({ @@ -34,12 +49,98 @@ describe("QueryAndResultSectionsComponent", () => { }); fixture = TestBed.createComponent(QueryAndResultSectionsComponent); component = fixture.componentInstance; + clipboard = TestBed.inject(Clipboard); + toastrService = TestBed.inject(ToastrService); + queryExplainerService = TestBed.inject(QueryExplainerService); + fileUploadService = TestBed.inject(FileUploadService); component.sqlLoading = false; - component.sqlRequestCode = ""; - fixture.detectChanges(); + component.sqlRequestCode = "select * from 'mock-dataset'"; }); it("should create", () => { expect(component).toBeTruthy(); }); + + it("should check that the progress bar for the editor disappears", fakeAsync(() => { + component.editorLoaded = false; + fixture.detectChanges(); + + expect(component.editorLoaded).toBeFalse(); + const progressBarElementBefore = findElementByDataTestId(fixture, "editor-progress-bar"); + expect(progressBarElementBefore).toBeDefined(); + + component.editorLoaded = true; + tick(); + fixture.detectChanges(); + + const progressBarElementAfter = findElementByDataTestId(fixture, "editor-progress-bar"); + expect(progressBarElementAfter).toBeUndefined(); + flush(); + })); + + it("should check invalid SQL result update", fakeAsync(() => { + component.sqlRequestCode = "select * from 'mock-dataset'"; + component.sqlError = mockSqlErrorUpdate.error; + tick(); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + const runSqlButton = findElementByDataTestId(fixture, "runSqlQueryButton") as HTMLButtonElement; + const elem = getElementByDataTestId(fixture, "sql-error-message"); + expect(runSqlButton.disabled).toBe(false); + expect(elem.textContent).toEqual(mockSqlErrorUpdate.error); + flush(); + })); + + it("should calculate sql request params", () => { + fixture.detectChanges(); + const sqlReq = spyOn(component.runSQLRequestEmit, "emit"); + const limit = 1; + const params = { + query: component.sqlRequestCode, + skip: component.currentData.length, + limit: limit, + }; + + component.loadMore(limit); + expect(sqlReq).toHaveBeenCalledWith(params); + + component.loadMore(limit); + params.skip = component.currentData.length; + + const secondCallParams = sqlReq.calls.allArgs()[1]; + expect(secondCallParams).toEqual([params]); + }); + + it("should check click on `Share query` button", fakeAsync(() => { + const toastServiceSpy = spyOn(toastrService, "success"); + const clipboardCopySpy = spyOn(clipboard, "copy"); + tick(); + fixture.detectChanges(); + + emitClickOnElementByDataTestId(fixture, "shareSqlQueryButton"); + expect(toastServiceSpy).toHaveBeenCalledWith("Copied url to clipboard"); + expect(clipboardCopySpy).toHaveBeenCalledTimes(1); + flush(); + })); + + it("should check click on `Copy as curl command` button", () => { + const toastServiceSpy = spyOn(toastrService, "success"); + const clipboardCopySpy = spyOn(clipboard, "copy"); + component.copyCurlCommand(); + expect(toastServiceSpy).toHaveBeenCalledWith("Copied command to clipboard"); + expect(clipboardCopySpy).toHaveBeenCalledTimes(1); + }); + + it("should check click on `Verify query result` button", () => { + const processQuerySpy = spyOn(queryExplainerService, "processQueryWithProof").and.returnValue( + of(mockQueryExplainerResponse), + ); + const uploadFilePrepareSpy = spyOn(fileUploadService, "uploadFilePrepare").and.returnValue( + of(mockUploadPrepareResponse), + ); + component.verifyQueryResult(); + expect(processQuerySpy).toHaveBeenCalledTimes(1); + expect(uploadFilePrepareSpy).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/app/dataset-view/dataset.component.spec.ts b/src/app/dataset-view/dataset.component.spec.ts index c5e54d01..ccdf8d1b 100644 --- a/src/app/dataset-view/dataset.component.spec.ts +++ b/src/app/dataset-view/dataset.component.spec.ts @@ -52,6 +52,7 @@ import { RouterTestingModule } from "@angular/router/testing"; import { promiseWithCatch } from "../common/app.helpers"; import { QueryAndResultSectionsComponent } from "./additional-components/data-component/query-and-result-sections/query-and-result-sections.component"; import { SavedQueriesSectionComponent } from "./additional-components/data-component/saved-queries-section/saved-queries-section.component"; +import { SqlQueryService } from "../services/sql-query.service"; describe("DatasetComponent", () => { let component: DatasetComponent; @@ -59,6 +60,7 @@ describe("DatasetComponent", () => { let datasetService: DatasetService; let datasetSubsServices: DatasetSubscriptionsService; let navigationService: NavigationService; + let sqlQueryService: SqlQueryService; let route: ActivatedRoute; let router: Router; const MOCK_DATASET_ROUTE = "kamu/mockNameDerived"; @@ -155,7 +157,7 @@ describe("DatasetComponent", () => { datasetSubsServices = TestBed.inject(DatasetSubscriptionsService); datasetSubsServices.emitPermissionsChanged(mockFullPowerDatasetPermissionsFragment); - + sqlQueryService = TestBed.inject(SqlQueryService); datasetService = TestBed.inject(DatasetService); router = TestBed.inject(Router); spyOnProperty(datasetService, "datasetChanges", "get").and.returnValue(of(mockDatasetBasicsDerivedFragment)); @@ -163,6 +165,7 @@ describe("DatasetComponent", () => { fixture = TestBed.createComponent(DatasetComponent); router.initialNavigation(); route = TestBed.inject(ActivatedRoute); + navigationService = TestBed.inject(NavigationService); component = fixture.componentInstance; component.datasetBasics = mockDatasetBasicsDerivedFragment; @@ -204,7 +207,7 @@ describe("DatasetComponent", () => { limit: AppValues.SQL_QUERY_LIMIT, }; - const requestDatasetDataSqlRunSpy = spyOn(datasetService, "requestDatasetDataSqlRun").and.returnValue(of()); + const requestDatasetDataSqlRunSpy = spyOn(sqlQueryService, "requestDataSqlRun").and.returnValue(of()); component.onRunSQLRequest(params); expect(requestDatasetDataSqlRunSpy).toHaveBeenCalledWith(params); }); @@ -282,7 +285,7 @@ describe("DatasetComponent", () => { limit: AppValues.SQL_QUERY_LIMIT, }; - spyOn(datasetService, "requestDatasetDataSqlRun").and.returnValue(of().pipe(delay(1000))); + spyOn(sqlQueryService, "requestDataSqlRun").and.returnValue(of().pipe(delay(1000))); component.onRunSQLRequest(params); tick(500); diff --git a/src/app/dataset-view/dataset.service.spec.ts b/src/app/dataset-view/dataset.service.spec.ts index 0267ffb5..f5110ec4 100644 --- a/src/app/dataset-view/dataset.service.spec.ts +++ b/src/app/dataset-view/dataset.service.spec.ts @@ -1,12 +1,9 @@ import { mockDatasetHeadBlockHashQuery } from "./../search/mock.data"; import { - mockDatasetDataSqlRunResponse, mockDatasetHistoryResponse, mockDatasetMainDataResponse, mockDatasetResponseNotFound, mockDatasetInfo, - mockDatasetDataSqlRunInvalidSqlResponse, - mockDatasetDataSqlRunInternalErrorResponse, mockFullPowerDatasetPermissionsFragment, mockDatasetLineageResponse, } from "../search/mock.data"; @@ -19,7 +16,6 @@ import { DatasetSubscriptionsService } from "./dataset.subscriptions.service"; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { ApolloTestingModule } from "apollo-angular/testing"; import { - DataQueryResultError, DataQueryResultErrorKind, DatasetBasicsFragment, DatasetDataSizeFragment, @@ -27,14 +23,9 @@ import { DatasetPermissionsFragment, MetadataBlockFragment, } from "../api/kamu.graphql.interface"; -import { of, throwError } from "rxjs"; +import { of } from "rxjs"; import { DatasetNotFoundError, SqlExecutionError } from "../common/errors"; -import { - DatasetHistoryUpdate, - DataSqlErrorUpdate, - LineageUpdate, - OverviewUpdate, -} from "./dataset.subscriptions.interface"; +import { DatasetHistoryUpdate, LineageUpdate, OverviewUpdate } from "./dataset.subscriptions.interface"; import { first } from "rxjs/operators"; import _ from "lodash"; import { mockDatasetBasicsWithPermissionQuery, TEST_ACCOUNT_NAME, TEST_DATASET_NAME } from "../api/mock/dataset.mock"; @@ -83,7 +74,7 @@ describe("AppDatasetService", () => { const metadataSchemaSubscription$ = datasetSubsService.metadataSchemaChanges.pipe(first()).subscribe(); - datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); + // datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); service.requestDatasetMainData(mockDatasetInfo).subscribe(); @@ -118,7 +109,7 @@ describe("AppDatasetService", () => { service.datasetChanges.subscribe(() => fail("Unexpected onDatasetChanges update")); datasetSubsService.overviewChanges.subscribe(() => fail("Unexpected overview update")); - datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); + // datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); datasetSubsService.metadataSchemaChanges.subscribe(() => fail("Unexpected metadata update")); const subscription$ = service @@ -149,7 +140,7 @@ describe("AppDatasetService", () => { service.datasetChanges.subscribe(() => fail("Unexpected onDatasetChanges update")); datasetSubsService.overviewChanges.subscribe(() => fail("Unexpected overview update")); - datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); + // datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); datasetSubsService.metadataSchemaChanges.subscribe(() => fail("Unexpected metadata update")); const subscription$ = service @@ -236,80 +227,6 @@ describe("AppDatasetService", () => { expect(subscription$.closed).toBeTrue(); }); - it("should check get SQL query data from api", () => { - const query = "select\n *\nfrom testTable"; - const limit = 20; - spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunResponse)); - - const subscriptionDataChanges$ = datasetSubsService.sqlQueryDataChanges.pipe(first()).subscribe(); - - const emitSqlErrorOccurredSpy = spyOn(datasetSubsService, "emitSqlErrorOccurred"); - - service.requestDatasetDataSqlRun({ query, limit }).subscribe(); - - expect(subscriptionDataChanges$.closed).toBeTrue(); - expect(emitSqlErrorOccurredSpy).toHaveBeenCalledWith({ error: "" }); - }); - - it("should check get SQL query data from api with invalid SQL", () => { - const query = "invalid sql query"; - const limit = 20; - spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunInvalidSqlResponse)); - - const subscriptionDataChanges$ = datasetSubsService.sqlQueryDataChanges.pipe(first()).subscribe(); - - const subscriptionErrorChanges$ = datasetSubsService.sqlErrorOccurrences - .pipe(first()) - .subscribe((update: DataSqlErrorUpdate) => { - const errorResult = mockDatasetDataSqlRunInvalidSqlResponse.data.query as DataQueryResultError; - expect(update.error).toEqual(errorResult.errorMessage); - }); - - service.requestDatasetDataSqlRun({ query, limit }).subscribe(); - - expect(subscriptionDataChanges$.closed).toBeFalse(); - expect(subscriptionErrorChanges$.closed).toBeTrue(); - }); - - it("should check get SQL query data from api when SQL execution fails softly", () => { - const query = "select\n *\nfrom testTable"; - const limit = 20; - spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunInternalErrorResponse)); - - datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); - datasetSubsService.sqlErrorOccurrences.subscribe(() => fail("Unexpected SQL error update")); - - const subscription$ = service - .requestDatasetDataSqlRun({ query, limit }) - .pipe(first()) - .subscribe({ - next: () => fail("Unexpected success"), - error: (e: Error) => { - const errorResult = mockDatasetDataSqlRunInternalErrorResponse.data.query as DataQueryResultError; - expect(e).toEqual(new SqlExecutionError(errorResult.errorMessage)); - }, - }); - expect(subscription$.closed).toBeTrue(); - }); - - it("should check get SQL query data from api when SQL execution fails hardly", () => { - const query = "select\n *\nfrom testTable"; - const limit = 20; - spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(throwError(() => new SqlExecutionError())); - - datasetSubsService.sqlQueryDataChanges.subscribe(() => fail("Unexpected data update")); - datasetSubsService.sqlErrorOccurrences.subscribe(() => fail("Unexpected SQL error update")); - - const subscription$ = service - .requestDatasetDataSqlRun({ query, limit }) - .pipe(first()) - .subscribe({ - next: () => fail("Unexpected success"), - error: (e: Error) => expect(e).toEqual(new SqlExecutionError()), - }); - expect(subscription$.closed).toBeTrue(); - }); - it("should check get dataset basics with permissions", () => { spyOn(datasetApi, "getDatasetBasicsWithPermissions").and.returnValue(of(mockDatasetBasicsWithPermissionQuery)); diff --git a/src/app/query/global-query/global-query.component.spec.ts b/src/app/query/global-query/global-query.component.spec.ts index 3f7ed1e9..9e4dc745 100644 --- a/src/app/query/global-query/global-query.component.spec.ts +++ b/src/app/query/global-query/global-query.component.spec.ts @@ -5,7 +5,6 @@ import { GlobalQueryComponent } from "./global-query.component"; import { EditorModule } from "src/app/shared/editor/editor.module"; import { CdkAccordionModule } from "@angular/cdk/accordion"; import { QueryAndResultSectionsComponent } from "src/app/dataset-view/additional-components/data-component/query-and-result-sections/query-and-result-sections.component"; -import { SharedTestModule } from "src/app/common/shared-test.module"; import { Apollo } from "apollo-angular"; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { MatMenuModule } from "@angular/material/menu"; @@ -18,6 +17,7 @@ import { MatIconModule } from "@angular/material/icon"; import { NgbTypeaheadModule } from "@ng-bootstrap/ng-bootstrap"; import { MatDividerModule } from "@angular/material/divider"; import { FormsModule } from "@angular/forms"; +import { SearchAndSchemasSectionComponent } from "./search-and-schemas-section/search-and-schemas-section.component"; describe("GlobalQueryComponent", () => { let component: GlobalQueryComponent; @@ -30,6 +30,7 @@ describe("GlobalQueryComponent", () => { SavedQueriesSectionComponent, RequestTimerComponent, QueryAndResultSectionsComponent, + SearchAndSchemasSectionComponent, ], imports: [ EditorModule, diff --git a/src/app/query/global-query/search-and-schemas-section/search-and-schemas-section.component.spec.ts b/src/app/query/global-query/search-and-schemas-section/search-and-schemas-section.component.spec.ts index 510376ba..d56b9a2f 100644 --- a/src/app/query/global-query/search-and-schemas-section/search-and-schemas-section.component.spec.ts +++ b/src/app/query/global-query/search-and-schemas-section/search-and-schemas-section.component.spec.ts @@ -1,5 +1,13 @@ +import { MatIconModule } from "@angular/material/icon"; +import { CdkAccordionModule } from "@angular/cdk/accordion"; import { ComponentFixture, TestBed } from "@angular/core/testing"; import { SearchAndSchemasSectionComponent } from "./search-and-schemas-section.component"; +import { SharedTestModule } from "src/app/common/shared-test.module"; +import { Apollo } from "apollo-angular"; +import { NgbTypeaheadModule } from "@ng-bootstrap/ng-bootstrap"; +import { FormsModule } from "@angular/forms"; +import { SavedQueriesSectionComponent } from "src/app/dataset-view/additional-components/data-component/saved-queries-section/saved-queries-section.component"; +import { MatDividerModule } from "@angular/material/divider"; describe("SearchAndSchemasSectionComponent", () => { let component: SearchAndSchemasSectionComponent; @@ -7,7 +15,16 @@ describe("SearchAndSchemasSectionComponent", () => { beforeEach(() => { TestBed.configureTestingModule({ - declarations: [SearchAndSchemasSectionComponent], + declarations: [SearchAndSchemasSectionComponent, SavedQueriesSectionComponent], + imports: [ + CdkAccordionModule, + MatIconModule, + MatDividerModule, + SharedTestModule, + NgbTypeaheadModule, + FormsModule, + ], + providers: [Apollo], }); fixture = TestBed.createComponent(SearchAndSchemasSectionComponent); component = fixture.componentInstance; diff --git a/src/app/services/sql-query.service.spec.ts b/src/app/services/sql-query.service.spec.ts index cb3845ba..f7cfdf4a 100644 --- a/src/app/services/sql-query.service.spec.ts +++ b/src/app/services/sql-query.service.spec.ts @@ -1,15 +1,104 @@ import { TestBed } from "@angular/core/testing"; import { SqlQueryService } from "./sql-query.service"; +import { of, first, throwError } from "rxjs"; +import { DatasetApi } from "../api/dataset.api"; +import { + mockDatasetDataSqlRunInternalErrorResponse, + mockDatasetDataSqlRunInvalidSqlResponse, + mockDatasetDataSqlRunResponse, +} from "../search/mock.data"; +import { Apollo } from "apollo-angular"; +import { DataQueryResultError } from "../api/kamu.graphql.interface"; +import { DataSqlErrorUpdate } from "../dataset-view/dataset.subscriptions.interface"; +import { SqlExecutionError } from "../common/errors"; describe("SqlQueryService", () => { let service: SqlQueryService; + let datasetApi: DatasetApi; beforeEach(() => { - TestBed.configureTestingModule({}); + TestBed.configureTestingModule({ + providers: [Apollo], + }); service = TestBed.inject(SqlQueryService); + datasetApi = TestBed.inject(DatasetApi); }); it("should be created", () => { expect(service).toBeTruthy(); }); + + it("should check get SQL query data from api", () => { + const query = "select\n *\nfrom testTable"; + const limit = 20; + spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunResponse)); + + const subscriptionDataChanges$ = service.sqlQueryResponseChanges.pipe(first()).subscribe(); + + const emitSqlErrorOccurredSpy = spyOn(service, "emitSqlErrorOccurred"); + + service.requestDataSqlRun({ query, limit }).subscribe(); + + expect(subscriptionDataChanges$.closed).toBeTrue(); + expect(emitSqlErrorOccurredSpy).toHaveBeenCalledWith({ error: "" }); + }); + + it("should check get SQL query data from api with invalid SQL", () => { + const query = "invalid sql query"; + const limit = 20; + spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunInvalidSqlResponse)); + + const subscriptionDataChanges$ = service.sqlQueryResponseChanges.pipe(first()).subscribe(); + + const subscriptionErrorChanges$ = service.sqlErrorOccurrences + .pipe(first()) + .subscribe((update: DataSqlErrorUpdate) => { + const errorResult = mockDatasetDataSqlRunInvalidSqlResponse.data.query as DataQueryResultError; + expect(update.error).toEqual(errorResult.errorMessage); + }); + + service.requestDataSqlRun({ query, limit }).subscribe(); + + expect(subscriptionDataChanges$.closed).toBeFalse(); + expect(subscriptionErrorChanges$.closed).toBeTrue(); + }); + + it("should check get SQL query data from api when SQL execution fails softly", () => { + const query = "select\n *\nfrom testTable"; + const limit = 20; + spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(of(mockDatasetDataSqlRunInternalErrorResponse)); + + service.sqlQueryResponseChanges.subscribe(() => fail("Unexpected data update")); + service.sqlErrorOccurrences.subscribe(() => fail("Unexpected SQL error update")); + + const subscription$ = service + .requestDataSqlRun({ query, limit }) + .pipe(first()) + .subscribe({ + next: () => fail("Unexpected success"), + error: (e: Error) => { + const errorResult = mockDatasetDataSqlRunInternalErrorResponse.data.query as DataQueryResultError; + expect(e).toEqual(new SqlExecutionError(errorResult.errorMessage)); + }, + }); + expect(subscription$.closed).toBeTrue(); + }); + + it("should check get SQL query data from api when SQL execution fails hardly", () => { + const query = "select\n *\nfrom testTable"; + const limit = 20; + spyOn(datasetApi, "getDatasetDataSqlRun").and.returnValue(throwError(() => new SqlExecutionError())); + + service.sqlQueryResponseChanges.subscribe(() => fail("Unexpected data update")); + service.sqlErrorOccurrences.subscribe(() => fail("Unexpected SQL error update")); + + const subscription$ = service + .requestDataSqlRun({ query, limit }) + .pipe(first()) + .subscribe({ + next: () => fail("Unexpected success"), + error: (e: Error) => expect(e).toEqual(new SqlExecutionError()), + }); + expect(subscription$.closed).toBeTrue(); + }); });