vendredi 20 octobre 2017

Angualar2 structural directive testing with TestBed

we implemented a structural directive in Angular 2 to show content only for users which have a specific role. In productive system everything works fine.

@Directive({ selector: '[pdHasRole]' })
export class UserHasRoleDirective {

    constructor(private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef,
        private userService: UserService) {
    }

    @Input() set pdHasRole(role: string) {

        this.viewContainer.clear();
        if (this.userService.userContext && this.userService.userContext.roles && this.userService.userContext.roles.length > 0) {
            if (role) {
                if (this.userService.userContext.roles.indexOf(role) > -1) {
                    this.viewContainer.createEmbeddedView(this.templateRef);
                }
            }
        }
    }
}

As we implemented some tests with TestBed the problems occured. If we used a role as an input which only contains letters and numbers (e.g. APP1role1) everything works fine. If we used a role with colons ect. (e.g. APP1:role1) we get an Error:

Template parse errors: TypeError: Cannot read property 'toUpperCase' of undefined

Here is the spec component for testing the structural directive:

describe('hasRole', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [TestHasRoleComponent],
            providers: [{ provide: UserService, useClass: FakeUserServiceWithRoles }],
            imports: [CommonModule, SharedModule]
        });
    });

    it('desired role; div should be included in DOM', () => {
        const role = 'APP1:role1';
        const template = `<div *pdHasRole="` + role + `">Test with role: ` + role + `</div>`;
        const fixture = createTestComponent(template)
        fixture.detectChanges();
        expect(fixture.debugElement.queryAll(By.css('div')).length).toEqual(1);
    });
});

@Component({ selector: 'pd-test-cmp', template: '' })
class TestHasRoleComponent {
}

function createTestComponent(template: string): ComponentFixture<TestHasRoleComponent> {
    return TestBed.overrideComponent(TestHasRoleComponent, { set: { template: template } })
        .createComponent(TestHasRoleComponent);
}

I am pretty sure the ':' in the role input causes the problem.

Has anybody an idea why? Help would be great!

Thanks in advance

Aucun commentaire:

Enregistrer un commentaire