From: Tiago Melo Date: Tue, 3 Jul 2018 13:38:35 +0000 (+0100) Subject: mgr/dashboard: Fix regression on rbd form component X-Git-Tag: v14.0.1~943^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F22829%2Fhead;p=ceph.git mgr/dashboard: Fix regression on rbd form component 'decodeURIComponent' method was decoding an undefined variable to the string 'undefined', which would later cause problems. This regression was introduced in057d6025894800c1b4a422b081fe02ab82b044fe. Fixes: http://tracker.ceph.com/issues/24757 Signed-off-by: Tiago Melo --- diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts index 762db57511d0..e11941120b50 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts @@ -1,17 +1,22 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { ToastModule } from 'ng2-toastr'; +import { ActivatedRouteStub } from '../../../../testing/activated-route-stub'; +import { RbdService } from '../../../shared/api/rbd.service'; import { SharedModule } from '../../../shared/shared.module'; import { configureTestBed } from '../../../shared/unit-test-helper'; +import { RbdFormMode } from './rbd-form-mode.enum'; import { RbdFormComponent } from './rbd-form.component'; describe('RbdFormComponent', () => { let component: RbdFormComponent; let fixture: ComponentFixture; + let activatedRoute: ActivatedRouteStub; configureTestBed({ imports: [ @@ -21,16 +26,47 @@ describe('RbdFormComponent', () => { ToastModule.forRoot(), SharedModule ], - declarations: [RbdFormComponent] + declarations: [RbdFormComponent], + providers: [ + { + provide: ActivatedRoute, + useValue: new ActivatedRouteStub({ pool: 'foo', name: 'bar', snap: undefined }) + } + ] }); beforeEach(() => { fixture = TestBed.createComponent(RbdFormComponent); component = fixture.componentInstance; - fixture.detectChanges(); + activatedRoute = TestBed.get(ActivatedRoute); }); it('should create', () => { expect(component).toBeTruthy(); }); + + describe('should test decodeURIComponent of params', () => { + let rbdService: RbdService; + + beforeEach(() => { + rbdService = TestBed.get(RbdService); + component.mode = RbdFormMode.editing; + fixture.detectChanges(); + spyOn(rbdService, 'get').and.callThrough(); + }); + + it('without snapName', () => { + activatedRoute.setParams({ pool: 'foo%2Ffoo', name: 'bar%2Fbar', snap: undefined }); + + expect(rbdService.get).toHaveBeenCalledWith('foo/foo', 'bar/bar'); + expect(component.snapName).toBeUndefined(); + }); + + it('with snapName', () => { + activatedRoute.setParams({ pool: 'foo%2Ffoo', name: 'bar%2Fbar', snap: 'baz%2Fbaz' }); + + expect(rbdService.get).toHaveBeenCalledWith('foo/foo', 'bar/bar'); + expect(component.snapName).toBe('baz/baz'); + }); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts index 164f8c9cde87..0d4b8785cf42 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts @@ -209,7 +209,9 @@ export class RbdFormComponent implements OnInit { this.route.params.subscribe((params: { pool: string; name: string; snap: string }) => { const poolName = decodeURIComponent(params.pool); const rbdName = decodeURIComponent(params.name); - this.snapName = decodeURIComponent(params.snap); + if (params.snap) { + this.snapName = decodeURIComponent(params.snap); + } this.rbdService.get(poolName, rbdName).subscribe((resp: RbdFormResponseModel) => { this.setResponse(resp, this.snapName); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts new file mode 100644 index 000000000000..fafbf60b4c6d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts @@ -0,0 +1,23 @@ +import { ReplaySubject } from 'rxjs'; + +/** + * An ActivateRoute test double with a `params` observable. + * Use the `setParams()` method to add the next `params` value. + */ +export class ActivatedRouteStub { + // Use a ReplaySubject to share previous values with subscribers + // and pump new values into the `params` observable + private subject = new ReplaySubject(); + + constructor(initialParams?: object) { + this.setParams(initialParams); + } + + /** The mock params observable */ + readonly params = this.subject.asObservable(); + + /** Set the params observables's next value */ + setParams(params?: object) { + this.subject.next(params); + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json b/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json index 719f72b9f831..24c953c44c5d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json +++ b/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json @@ -9,6 +9,7 @@ "exclude": [ "app/shared/unit-test-helper.ts", "test.ts", + "testing/*.ts", "**/*.spec.ts" ] } diff --git a/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json b/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json index 18bad40ed42a..b5de1d67b30c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json +++ b/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json @@ -16,6 +16,7 @@ ], "include": [ "**/*.spec.ts", - "**/*.d.ts" + "**/*.d.ts", + "testing/*.ts" ] }