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

Fix Spec has no expectations errors #2371

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bfaea74
Throw error for tests without expectations
alexandrevryghem Jul 1, 2023
3640d75
Fix objectUpdatesReducer no expectation tests
alexandrevryghem Jul 1, 2023
abc8640
Fix MetadataRepresentationListElementComponent no expectation tests
alexandrevryghem Jul 1, 2023
e0db428
Fix CollectionSearchResultListElementComponent no expectation tests
alexandrevryghem Jul 1, 2023
063c54e
Fix SearchHierarchyFilterComponent no expectation tests
alexandrevryghem Jul 1, 2023
7ef3a91
Fix ItemComponent no expectation tests
alexandrevryghem Jul 1, 2023
9d71171
Fix ItemVersionsComponent no expectation tests
alexandrevryghem Jul 1, 2023
a524805
Fix CommunitySearchResultListElementComponent no expectation tests
alexandrevryghem Jul 1, 2023
b83a0b3
Fix SubmissionSectionUploadFileComponent no expectation tests
alexandrevryghem Jul 1, 2023
b4a3882
Fix findSuccessfulAccordingTo no expectation tests
alexandrevryghem Jul 1, 2023
c1875ca
Add expect().nothing() to reducer tests without expectations, who onl…
alexandrevryghem Jul 1, 2023
c2010b5
Fix SubscriptionsDataService no expectation tests
alexandrevryghem Jul 2, 2023
b7dfe0f
Fix EPersonDataService no expectation tests
alexandrevryghem Jul 8, 2023
4b1a8a9
Fix ObjectUpdatesEffects no expectation tests
alexandrevryghem Jul 12, 2023
430b3b2
Fix TopLevelCommunityListComponent, CommunityPageSubCollectionListCom…
alexandrevryghem Jul 15, 2023
b8b9da2
Fix BrowseByComponent no expectation tests
alexandrevryghem Jul 15, 2023
8d84efb
Fix AuthInterceptor no expectation tests
alexandrevryghem Jul 16, 2023
c4bff4d
Fix test without it's/it's not running because they are in a waitForA…
alexandrevryghem Jul 29, 2023
aa42a7e
Merge remote-tracking branch 'upstream/main' into fix-specs-without-e…
alexandrevryghem Dec 15, 2023
230adc1
Fixed failing EPeopleRegistryComponent test
alexandrevryghem Dec 15, 2023
b577120
Merge remote-tracking branch 'upstream/main' into fix-specs-without-e…
alexandrevryghem Feb 18, 2024
bba6971
Fixed new failing tests
alexandrevryghem Feb 18, 2024
109418b
Merge remote-tracking branch 'upstream/main' into fix-specs-without-e…
alexandrevryghem Feb 24, 2024
db710c5
Fixed some components not destroying their ViewContainerRef
alexandrevryghem Feb 24, 2024
a340eb2
Removed broken tests
alexandrevryghem Feb 29, 2024
87788e7
Merge remote-tracking branch 'upstream/main' into fix-specs-without-e…
alexandrevryghem Feb 29, 2024
371e766
Fixed tests without expectations from #2759 & #2681
alexandrevryghem Feb 29, 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
5 changes: 4 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ module.exports = function (config) {
],
client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser
captureConsole: false
captureConsole: false,
jasmine: {
failSpecWithNoExpectations: true
}
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/dspace-angular'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { NgbModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
Expand All @@ -18,8 +18,6 @@ import { EPeopleRegistryComponent } from './epeople-registry.component';
import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { getMockFormBuilderService } from '../../shared/mocks/form-builder-service.mock';
import { getMockTranslateService } from '../../shared/mocks/translate.service.mock';
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import { RouterStub } from '../../shared/testing/router.stub';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
Expand All @@ -31,17 +29,15 @@ import { FindListOptions } from '../../core/data/find-list-options.model';
describe('EPeopleRegistryComponent', () => {
let component: EPeopleRegistryComponent;
let fixture: ComponentFixture<EPeopleRegistryComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;

let mockEPeople;
let mockEPeople: EPerson[];
let ePersonDataServiceStub: any;
let authorizationService: AuthorizationDataService;
let modalService;
let modalService: NgbModal;
let paginationService: PaginationServiceStub;

let paginationService;

beforeEach(waitForAsync(() => {
beforeEach(waitForAsync(async () => {
jasmine.getEnv().allowRespy(true);
mockEPeople = [EPersonMock, EPersonMock2];
ePersonDataServiceStub = {
Expand Down Expand Up @@ -99,7 +95,7 @@ describe('EPeopleRegistryComponent', () => {
deleteEPerson(ePerson: EPerson): Observable<boolean> {
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
return (ePerson2.uuid !== ePerson.uuid);
});
});
return observableOf(true);
},
editEPerson(ePerson: EPerson) {
Expand All @@ -119,17 +115,11 @@ describe('EPeopleRegistryComponent', () => {
isAuthorized: observableOf(true)
});
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();

paginationService = new PaginationServiceStub();
TestBed.configureTestingModule({
await TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock
}
}),
TranslateModule.forRoot(),
],
declarations: [EPeopleRegistryComponent],
providers: [
Expand All @@ -148,7 +138,7 @@ describe('EPeopleRegistryComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(EPeopleRegistryComponent);
component = fixture.componentInstance;
modalService = (component as any).modalService;
modalService = TestBed.inject(NgbModal);
spyOn(modalService, 'open').and.returnValue(Object.assign({ componentInstance: Object.assign({ response: observableOf(true) }) }));
fixture.detectChanges();
});
Expand All @@ -158,18 +148,18 @@ describe('EPeopleRegistryComponent', () => {
});

it('should display list of ePeople', () => {
const ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
const ePeopleIdsFound: DebugElement[] = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
expect(ePeopleIdsFound.length).toEqual(2);
mockEPeople.map((ePerson: EPerson) => {
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === ePerson.uuid);
})).toBeTruthy();
});
});

describe('search', () => {
describe('when searching with scope/query (scope metadata)', () => {
let ePeopleIdsFound;
let ePeopleIdsFound: DebugElement[];
beforeEach(fakeAsync(() => {
component.search({ scope: 'metadata', query: EPersonMock2.name });
tick();
Expand All @@ -179,14 +169,14 @@ describe('EPeopleRegistryComponent', () => {

it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock2.uuid);
})).toBeTruthy();
});
});

describe('when searching with scope/query (scope email)', () => {
let ePeopleIdsFound;
let ePeopleIdsFound: DebugElement[];
beforeEach(fakeAsync(() => {
component.search({ scope: 'email', query: EPersonMock.email });
tick();
Expand All @@ -196,7 +186,7 @@ describe('EPeopleRegistryComponent', () => {

it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock.uuid);
})).toBeTruthy();
});
Expand Down Expand Up @@ -228,19 +218,12 @@ describe('EPeopleRegistryComponent', () => {
});
});

describe('delete EPerson button when the isAuthorized returns false', () => {
let ePeopleDeleteButton;
beforeEach(() => {
spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false));
component.initialisePage();
fixture.detectChanges();
});

it('should be disabled', () => {
ePeopleDeleteButton = fixture.debugElement.queryAll(By.css('#epeople tr td div button.delete-button'));
ePeopleDeleteButton.forEach((deleteButton: DebugElement) => {
expect(deleteButton.nativeElement.disabled).toBe(true);
});
});
it('should hide delete EPerson button when the isAuthorized returns false', () => {
spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false));
component.initialisePage();
fixture.detectChanges();

expect(fixture.debugElement.query(By.css('#epeople tr td div button.delete-button'))).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
Expand Down Expand Up @@ -30,7 +30,7 @@ import { ConfigurationProperty } from '../../../../core/shared/configuration-pro
import { createPaginatedList } from '../../../../shared/testing/utils.test';
import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service.stub';

describe('CommunityPageSubCollectionList Component', () => {
describe('CommunityPageSubCollectionListComponent', () => {
let comp: CommunityPageSubCollectionListComponent;
let fixture: ComponentFixture<CommunityPageSubCollectionListComponent>;
let collectionDataServiceStub: any;
Expand Down Expand Up @@ -177,19 +177,19 @@ describe('CommunityPageSubCollectionList Component', () => {
});


it('should display a list of collections', () => {
waitForAsync(() => {
subCollList = collections;
fixture.detectChanges();
it('should display a list of collections', async () => {
subCollList = collections;
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();

const collList = fixture.debugElement.queryAll(By.css('li'));
expect(collList.length).toEqual(5);
expect(collList[0].nativeElement.textContent).toContain('Collection 1');
expect(collList[1].nativeElement.textContent).toContain('Collection 2');
expect(collList[2].nativeElement.textContent).toContain('Collection 3');
expect(collList[3].nativeElement.textContent).toContain('Collection 4');
expect(collList[4].nativeElement.textContent).toContain('Collection 5');
});
const collList: DebugElement[] = fixture.debugElement.queryAll(By.css('ul[data-test="objects"] li'));
expect(collList.length).toEqual(5);
expect(collList[0].nativeElement.textContent).toContain('Collection 1');
expect(collList[1].nativeElement.textContent).toContain('Collection 2');
expect(collList[2].nativeElement.textContent).toContain('Collection 3');
expect(collList[3].nativeElement.textContent).toContain('Collection 4');
expect(collList[4].nativeElement.textContent).toContain('Collection 5');
});

it('should not display the header when list of collections is empty', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser';
Expand Down Expand Up @@ -30,7 +30,7 @@ import { SearchConfigurationServiceStub } from '../../../../shared/testing/searc
import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model';
import { createPaginatedList } from '../../../../shared/testing/utils.test';

describe('CommunityPageSubCommunityListComponent Component', () => {
describe('CommunityPageSubCommunityListComponent', () => {
let comp: CommunityPageSubCommunityListComponent;
let fixture: ComponentFixture<CommunityPageSubCommunityListComponent>;
let communityDataServiceStub: any;
Expand Down Expand Up @@ -179,19 +179,19 @@ describe('CommunityPageSubCommunityListComponent Component', () => {
});


it('should display a list of sub-communities', () => {
waitForAsync(() => {
subCommList = subcommunities;
fixture.detectChanges();
it('should display a list of sub-communities', async () => {
subCommList = subcommunities;
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();

const subComList = fixture.debugElement.queryAll(By.css('li'));
expect(subComList.length).toEqual(5);
expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1');
expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2');
expect(subComList[2].nativeElement.textContent).toContain('SubCommunity 3');
expect(subComList[3].nativeElement.textContent).toContain('SubCommunity 4');
expect(subComList[4].nativeElement.textContent).toContain('SubCommunity 5');
});
const subComList: DebugElement[] = fixture.debugElement.queryAll(By.css('ul[data-test="objects"] li'));
expect(subComList.length).toEqual(5);
expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1');
expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2');
expect(subComList[2].nativeElement.textContent).toContain('SubCommunity 3');
expect(subComList[3].nativeElement.textContent).toContain('SubCommunity 4');
expect(subComList[4].nativeElement.textContent).toContain('SubCommunity 5');
});

it('should not display the header when list of sub-communities is empty', () => {
Expand Down
13 changes: 6 additions & 7 deletions src/app/core/auth/auth.interceptor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ describe(`AuthInterceptor`, () => {

const authServiceStub = new AuthServiceStub();
const store: Store<TruncatablesState> = jasmine.createSpyObj('store', {
/* eslint-disable no-empty,@typescript-eslint/no-empty-function */
dispatch: {},
/* eslint-enable no-empty, @typescript-eslint/no-empty-function */
select: observableOf(true)
});

Expand All @@ -46,6 +44,10 @@ describe(`AuthInterceptor`, () => {
httpMock = TestBed.inject(HttpTestingController);
});

afterEach(() => {
httpMock.verify();
});

describe('when has a valid token', () => {

it('should not add an Authorization header when we’re sending a HTTP request to \'authn\' endpoint that is not the logout endpoint', () => {
Expand Down Expand Up @@ -95,14 +97,11 @@ describe(`AuthInterceptor`, () => {
});

it('should redirect to login', () => {

service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user').subscribe((response) => {
expect(response).toBeTruthy();
});

service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user');

httpMock.expectNone('dspace-spring-rest/api/submission/workspaceitems');
// HttpTestingController.expectNone will throw an error when a requests is made
expect().nothing();
});
});

Expand Down
16 changes: 16 additions & 0 deletions src/app/core/cache/object-cache.reducer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ describe('objectCacheReducer', () => {
deepFreeze(state);

objectCacheReducer(state, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should remove the specified object from the cache in response to the REMOVE action', () => {
Expand All @@ -149,6 +153,10 @@ describe('objectCacheReducer', () => {
const action = new RemoveFromObjectCacheAction(selfLink1);
// testState has already been frozen above
objectCacheReducer(testState, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should set the timestamp of all objects in the cache in response to a RESET_TIMESTAMPS action', () => {
Expand All @@ -164,6 +172,10 @@ describe('objectCacheReducer', () => {
const action = new ResetObjectCacheTimestampsAction(new Date().getTime());
// testState has already been frozen above
objectCacheReducer(testState, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should perform the ADD_PATCH action without affecting the previous state', () => {
Expand All @@ -174,6 +186,10 @@ describe('objectCacheReducer', () => {
}]);
// testState has already been frozen above
objectCacheReducer(testState, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should when the ADD_PATCH action dispatched', () => {
Expand Down
8 changes: 8 additions & 0 deletions src/app/core/cache/server-sync-buffer.reducer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,20 @@ describe('serverSyncBufferReducer', () => {
const action = new AddToSSBAction(selfLink1, RestRequestMethod.POST);
// testState has already been frozen above
serverSyncBufferReducer(testState, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should perform the EMPTY action without affecting the previous state', () => {
const action = new EmptySSBAction();
// testState has already been frozen above
serverSyncBufferReducer(testState, action);

// no expect required, deepFreeze will ensure an exception is thrown if the state
// is mutated, and any uncaught exception will cause the test to fail
expect().nothing();
});

it('should empty the buffer if the EmptySSBAction is dispatched without a payload', () => {
Expand Down
Loading
Loading