diff --git a/src/app/core/data/eperson-registration.service.spec.ts b/src/app/core/data/eperson-registration.service.spec.ts index fe3a1958eb..768d83c024 100644 --- a/src/app/core/data/eperson-registration.service.spec.ts +++ b/src/app/core/data/eperson-registration.service.spec.ts @@ -8,8 +8,11 @@ import { Registration } from '../shared/registration.model'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { of as observableOf } from 'rxjs/internal/observable/of'; +import { TestScheduler } from 'rxjs/testing'; describe('EpersonRegistrationService', () => { + let testScheduler; + let service: EpersonRegistrationService; let requestService: RequestService; @@ -29,6 +32,12 @@ describe('EpersonRegistrationService', () => { rd = createSuccessfulRemoteDataObject(registrationWithUser); halService = new HALEndpointServiceStub('rest-url'); + testScheduler = new TestScheduler((actual, expected) => { + // asserting the two objects are equal + // e.g. using chai. + expect(actual).toEqual(expected); + }); + requestService = jasmine.createSpyObj('requestService', { generateRequestId: 'request-id', send: {}, @@ -36,7 +45,8 @@ describe('EpersonRegistrationService', () => { { a: Object.assign(new RequestEntry(), { response: new RestResponse(true, 200, 'Success') }) }) }); rdbService = jasmine.createSpyObj('rdbService', { - buildFromRequestUUID: observableOf(rd) + buildSingle: observableOf(rd), + buildFromRequestUUID: observableOf(rd), }); service = new EpersonRegistrationService( requestService, @@ -86,8 +96,28 @@ describe('EpersonRegistrationService', () => { user: registrationWithUser.user }) })); - }); + + // tslint:disable:no-shadowed-variable + it('should use cached responses and /registrations/search/findByToken?', () => { + testScheduler.run(({ cold, expectObservable }) => { + rdbService.buildSingle.and.returnValue(cold('a', { a: rd })); + + service.searchByToken('test-token'); + + expect(requestService.send).toHaveBeenCalledWith( + jasmine.objectContaining({ + uuid: 'request-id', method: 'GET', + href: 'rest-url/registrations/search/findByToken?token=test-token', + }), true + ); + expectObservable(rdbService.buildSingle.calls.argsFor(0)[0]).toBe('(a|)', { + a: 'rest-url/registrations/search/findByToken?token=test-token' + }); + }); + }); + }); }); +/**/ diff --git a/src/app/core/data/eperson-registration.service.ts b/src/app/core/data/eperson-registration.service.ts index fd55c031d8..adf01b0ce9 100644 --- a/src/app/core/data/eperson-registration.service.ts +++ b/src/app/core/data/eperson-registration.service.ts @@ -3,7 +3,7 @@ import { RequestService } from './request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { GetRequest, PostRequest } from './request.models'; import { Observable } from 'rxjs'; -import { filter, find, map, take } from 'rxjs/operators'; +import { filter, find, map, skipWhile } from 'rxjs/operators'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { Registration } from '../shared/registration.model'; import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../shared/operators'; @@ -60,9 +60,9 @@ export class EpersonRegistrationService { const requestId = this.requestService.generateRequestId(); - const hrefObs = this.getRegistrationEndpoint(); + const href$ = this.getRegistrationEndpoint(); - hrefObs.pipe( + href$.pipe( find((href: string) => hasValue(href)), map((href: string) => { const request = new PostRequest(requestId, href, registration); @@ -82,27 +82,28 @@ export class EpersonRegistrationService { searchByToken(token: string): Observable { const requestId = this.requestService.generateRequestId(); - const hrefObs = this.getTokenSearchEndpoint(token); - - hrefObs.pipe( + const href$ = this.getTokenSearchEndpoint(token).pipe( find((href: string) => hasValue(href)), - map((href: string) => { - const request = new GetRequest(requestId, href); - Object.assign(request, { - getResponseParser(): GenericConstructor { - return RegistrationResponseParsingService; - } - }); - this.requestService.send(request, true); - }) - ).subscribe(); + ); - return this.rdbService.buildFromRequestUUID(requestId).pipe( + href$.subscribe((href: string) => { + const request = new GetRequest(requestId, href); + Object.assign(request, { + getResponseParser(): GenericConstructor { + return RegistrationResponseParsingService; + } + }); + this.requestService.send(request, true); + }); + + return this.rdbService.buildSingle(href$).pipe( + skipWhile((rd: RemoteData) => rd.isStale), getFirstSucceededRemoteData(), map((restResponse: RemoteData) => { - return Object.assign(new Registration(), {email: restResponse.payload.email, token: token, user: restResponse.payload.user}); + return Object.assign(new Registration(), { + email: restResponse.payload.email, token: token, user: restResponse.payload.user + }); }), - take(1), ); } diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index 98188a07e8..707c70f19c 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -11,6 +11,7 @@ import { Store } from '@ngrx/store'; import { CoreState } from '../../core/core.reducers'; import { RemoteData } from '../../core/data/remote-data'; import { EPerson } from '../../core/eperson/models/eperson.model'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; @Component({ selector: 'ds-forgot-password-form', @@ -70,7 +71,9 @@ export class ForgotPasswordFormComponent { */ submit() { if (!this.isInValid) { - this.ePersonDataService.patchPasswordWithToken(this.user, this.token, this.password).subscribe((response: RemoteData) => { + this.ePersonDataService.patchPasswordWithToken(this.user, this.token, this.password).pipe( + getFirstCompletedRemoteData() + ).subscribe((response: RemoteData) => { if (response.hasSucceeded) { this.notificationsService.success( this.translateService.instant(this.NOTIFICATIONS_PREFIX + '.success.title'),