Не удается прочитать свойство 'toUpperCase' из неопределенного во всех тестах - PullRequest
0 голосов
/ 16 мая 2019

У меня возникли некоторые проблемы с моим модулем Жасмин Test.

Все мои тесты в одном файле выдают эту ошибку:

"Невозможно прочитать свойство 'toUpperCase' изundefined "

Я попытался поместить весь импорт из модуля в импорт файла теста, но у меня нет успеха

.html

<div class="km-btn-group" *ngIf="create">
    <button class="km-btn km-btn-cancel" type="button" (click)="delete()">descartar bot</button>
    <button *ngIf="botThirdStep?.type?.toUpperCase() == 'FAQ'" class="km-btn km-btn-default" type="button" (click)="cleanStep()">remover
        selecionados</button>
    <button class="km-btn km-btn-success" type="button" (click)="goToReview()">concluir</button>
</div>

<div class="km-btn-group" *ngIf="!create">
    <button class="km-btn km-btn-cancel" type="button" (click)="cancel()">cancelar</button>
    <!-- <button *ngIf="botThirdStep?.type?.toUpperCase() == 'FAQ'" class="km-btn km-btn-default" type="button" (click)="reset()">limpar
        alterações</button> -->
    <button class="km-btn km-btn-success" type="button" (click)="saveChanges()">salvar</button>
</div>

<card-structured-dialog *ngIf="botThirdStep?.type?.toUpperCase() == 'STRUCTURED'" class="km-structured-dialog"></card-structured-dialog>

<div *ngIf="botThirdStep?.type?.toUpperCase() != 'STRUCTURED'" class="row no-gutters km-newbot-wrap">

    <div class="col-md-4">
        <div class="card km-card km-newbot-card">
            <h2 class="km-newbot-card-title">Assuntos Selecionados</h2>
            <app-loading *ngIf="loading"></app-loading>
            <ul *ngIf="!loading" class="list-unstyled km-newbot-dragarea" dragula="SUBJECTS" [(dragulaModel)]='selected'>
                <li *ngFor="let subject of selected">
                    <app-bot-subject [botSubjects]="subject" remove="true" (backToAvailable)="goBackToAvailable(subject.id)"></app-bot-subject>
                </li>
            </ul>
        </div>
    </div>

    <div class="col-md-8">
        <div class="card km-card km-newbot-card">
            <div class="row km-newbot-card-title">
                <div class="col-md-5 col-lg-4">
                    <h2>Assuntos Disponíveis</h2>
                </div>
                <div *ngIf="!loading" class="col-md-7 col-lg-8 km-newbot-search">
                    <app-input name="search" placeholder="Qual Assunto você procura?" [value]="filter" (bindValue)="debounce.next($event)"
                        urlimg="../../../assets/images/search.png">
                    </app-input>
                </div>
            </div>
            <app-loading *ngIf="loading"></app-loading>
            <ul *ngIf="!loading" class="row list-unstyled km-newbot-droparea" dragula="SUBJECTS" [(dragulaModel)]='available'>
                <li class="col-xs-12 col-sm-6" *ngFor="let subject of available | filterByParam: 'name':filter | orderByParam: 'name'">
                    <app-bot-subject [botSubjects]="subject"></app-bot-subject>
                </li>
            </ul>
        </div>
    </div>

</div><div class="km-btn-group" *ngIf="create">
    <button class="km-btn km-btn-cancel" type="button" (click)="delete()">descartar bot</button>
    <button *ngIf="botThirdStep?.type?.toUpperCase() == 'FAQ'" class="km-btn km-btn-default" type="button" (click)="cleanStep()">remover
        selecionados</button>
    <button class="km-btn km-btn-success" type="button" (click)="goToReview()">concluir</button>
</div>

<div class="km-btn-group" *ngIf="!create">
    <button class="km-btn km-btn-cancel" type="button" (click)="cancel()">cancelar</button>
    <!-- <button *ngIf="botThirdStep?.type?.toUpperCase() == 'FAQ'" class="km-btn km-btn-default" type="button" (click)="reset()">limpar
        alterações</button> -->
    <button class="km-btn km-btn-success" type="button" (click)="saveChanges()">salvar</button>
</div>

<card-structured-dialog *ngIf="botThirdStep?.type?.toUpperCase() == 'STRUCTURED'" class="km-structured-dialog"></card-structured-dialog>

<div *ngIf="botThirdStep?.type?.toUpperCase() != 'STRUCTURED'" class="row no-gutters km-newbot-wrap">

    <div class="col-md-4">
        <div class="card km-card km-newbot-card">
            <h2 class="km-newbot-card-title">Assuntos Selecionados</h2>
            <app-loading *ngIf="loading"></app-loading>
            <ul *ngIf="!loading" class="list-unstyled km-newbot-dragarea" dragula="SUBJECTS" [(dragulaModel)]='selected'>
                <li *ngFor="let subject of selected">
                    <app-bot-subject [botSubjects]="subject" remove="true" (backToAvailable)="goBackToAvailable(subject.id)"></app-bot-subject>
                </li>
            </ul>
        </div>
    </div>

    <div class="col-md-8">
        <div class="card km-card km-newbot-card">
            <div class="row km-newbot-card-title">
                <div class="col-md-5 col-lg-4">
                    <h2>Assuntos Disponíveis</h2>
                </div>
                <div *ngIf="!loading" class="col-md-7 col-lg-8 km-newbot-search">
                    <app-input name="search" placeholder="Qual Assunto você procura?" [value]="filter" (bindValue)="debounce.next($event)"
                        urlimg="../../../assets/images/search.png">
                    </app-input>
                </div>
            </div>
            <app-loading *ngIf="loading"></app-loading>
            <ul *ngIf="!loading" class="row list-unstyled km-newbot-droparea" dragula="SUBJECTS" [(dragulaModel)]='available'>
                <li class="col-xs-12 col-sm-6" *ngFor="let subject of available | filterByParam: 'name':filter | orderByParam: 'name'">
                    <app-bot-subject [botSubjects]="subject"></app-bot-subject>
                </li>
            </ul>
        </div>
    </div>

</div>

.ts

@Component({
    selector: 'app-step-third',
    templateUrl: './step-third.component.html',
    styleUrls: ['./step-third.component.scss']
})
export class StepThirdComponent implements OnInit, OnDestroy {

    private loading = false;
    private filter = '';
    private debounce: Subject<string> = new Subject<string>();
    private subs = new Subscription();
    private compareAvailable: BotSubject[] = [];
    private compareSelected: BotSubject[] = [];
    @Input() autosave = false;
    @Input() create = true;
    @Input() botThirdStep: Bot;
    @Input() available: BotSubject[] = [];
    @Input() selected: BotSubject[] = [];
    @Output() relodSubjects: EventEmitter<any> = new EventEmitter();
    @Output() deleteDraft: EventEmitter<any> = new EventEmitter();
    @Output() goBack: EventEmitter<any> = new EventEmitter();
    private user: UserModel;
    private userColaboratorInformation: UserColaboratorInformation

    constructor(
        private router: Router,
        private dragulaService: DragulaService,
        private subjectService: BotSubjectService
    ) {
        this.user = new UserModel();
        this.user = JSON.parse(window.localStorage.getItem('userLogged'));
        this.userColaboratorInformation = new UserColaboratorInformation();
        this.userColaboratorInformation = JSON.parse(window.localStorage.getItem('userColaboratorInformation'));
    }

    ngOnInit(): void {
        if ((this.botThirdStep.type.toUpperCase() === 'STRUCTURED') && !(this.selected.length === 0))
            this.cleanStep()


        window.scrollTo(0, 0);
        this.debounce
            .subscribe(filter => this.filter = filter);

        if (this.autosave) {
            this.subs.add(this.dragulaService.dropModel('SUBJECTS')
                .subscribe(({ sourceModel, targetModel, item }) => {
                    if (sourceModel !== targetModel) {
                        this.updateSubject(this.botThirdStep._id, item.id, false);
                    }
                })
            );
        } else {
            this.compareAvailable = this.available;
            this.compareSelected = this.selected;
        }

    }

    ngOnDestroy(): void {
        this.debounce.unsubscribe();
        this.subs.unsubscribe();
    }

    public updateSubject(botId: string, subjectId: string, reload: boolean): void {
        this.loading = true;
        const data: changeSubject = {
            userName: this.userColaboratorInformation.employeeName,
            userRole: this.userColaboratorInformation.occupationName,
        };
        this.subjectService.updateSubject(botId, subjectId, data)
            // .map((res: Response) => (res.json()))
            .subscribe((res) => {
                this.loading = false;
                if (reload) {
                    this.relodSubjects.emit();
                }
            }, (err) => {
                this.loading = false;
                if (reload) {
                    this.relodSubjects.emit();
                }
            });
    }

    public cleanStep(): void {
        if (this.autosave) {
            this.selected.forEach(subject => {
                this.updateSubject(this.botThirdStep._id, subject.id, true);
            });
        }
    }

    public delete(): void {
        this.deleteDraft.emit();
    }

    public goToReview(): void {
        this.router.navigateByUrl('/bot/review-draft/' + this.botThirdStep._id);
    }

    public goBackToAvailable(subjectId): void {
        if (this.autosave) {
            this.updateSubject(this.botThirdStep._id, subjectId, true);
        } else {
            this.loading = true;
            this.filter = ' ';
            let auxIndex = -1;
            let auxObj: BotSubject;
            this.selected.forEach((element, index) => {
                if (element.id === subjectId) {
                    auxIndex = index;
                    auxObj = element;
                }
            });
            if (auxIndex >= 0) {
                setTimeout(() => {
                    this.selected.splice(auxIndex, 1);
                    this.available.push(auxObj);
                    this.filter = null;
                    this.loading = false;
                }, 100);
            }
        }
    }

    public saveChanges(): void {
        this.loading = true;
        let sendToChange: BotSubject[];
        sendToChange = this.objectsInBoth(this.compareAvailable, this.selected).concat(this.objectsInBoth(this.compareSelected, this.available));
        if (sendToChange.length > 0) {
            this.subjectService.swapSelected(this.botThirdStep._id, this.jsonWithOnlySubjectId(sendToChange))
                // .map((res: Response) => (res.json()))
                .subscribe((res) => {
                    this.loading = false;
                    this.goBack.emit();
                }, (err) => {
                    this.loading = false;
                    alert('Ocorreu algum erro ao tentar salvar as alterações. Por favor tente novamente');
                });
        } else {
            this.goBack.emit();
        }
    }

    public objectsInBoth(mainArray, compareArray): BotSubject[] {
        const hasInBoth = [];
        mainArray.forEach(obj => {
            if (compareArray.includes(obj)) {
                hasInBoth.push(obj);
            }
        });
        return hasInBoth;
    }

    public jsonWithOnlySubjectId(array: BotSubject[]) {
        const normalizeArray = [];
        for (const object of array) {
            normalizeArray.push({ 'id': object.id });
        }
        const json = {
            'userName': 'Maycon pacheco',
            'userRole': 'Back',
            'subjects': normalizeArray
        };
        return json;
    }

    public cancel(): void {
        this.goBack.emit();
    }

}

.spec

class MockDragulaService {
    dropModel = jasmine.createSpy('dropModel').and.returnValue(
        Observable.of({
            name: '',
            el: undefined,
            target: undefined,
            source: undefined,
            sibling: undefined,
            item: { id: 111 },
            sourceModel: [1],
            targetModel: [2],
            sourceIndex: 0,
            targetIndex: 0
        })
    );
}

class MockBotSubjectService {
    updateSubject = jasmine.createSpy('updateSubject').and.returnValue(Observable.of({ attr: 'test' }));
}

fdescribe('StepThirdComponent', () => {
    let component: StepThirdComponent;
    let fixture: ComponentFixture<StepThirdComponent>;
    const router = {
        navigateByUrl: jasmine.createSpy('navigateByUrl'),    // to spy on the url that has been routed
    };
    let dragulaServiceSpy: DragulaService;
    let botSubjectServiceSpy: BotSubjectService;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [

            ],
            declarations: [
                StepThirdComponent,
                // SubjectStubComponent,
                // InputStubComponent,
                FilterByParamPipe,
                OrderByParamPipe,
            ],
            schemas: [
                NO_ERRORS_SCHEMA
            ],
            providers: [
                { provide: Router, useValue: router },
                { provide: DragulaService, useClass: MockDragulaService },
                { provide: BotSubjectService, useClass: MockBotSubjectService },
            ]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(StepThirdComponent);
        component = fixture.componentInstance;
        component.botThirdStep = { _id: 'test' };
        fixture.detectChanges();
        dragulaServiceSpy = fixture.debugElement.injector.get(DragulaService);
        botSubjectServiceSpy = fixture.debugElement.injector.get(BotSubjectService);
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('should test updateSubject called on ngOnInit if autosave is true', () => {
        component['debounce'] = new Subject<string>();
        component['subs'] = new Subscription();
        component['autosave'] = true;
        component.ngOnInit();
        expect(botSubjectServiceSpy.updateSubject).toHaveBeenCalled();
    });

    it('should test ngOnDestroy', () => {
        spyOn(component['debounce'], 'unsubscribe');
        spyOn(component['subs'], 'unsubscribe');
        component.ngOnDestroy();
        expect(component['debounce'].unsubscribe).toHaveBeenCalled();
        expect(component['subs'].unsubscribe).toHaveBeenCalled();
    });

    describe('should test updateSubject', () => {
        it('should test updateSubject for reload = false', () => {
            const mockData: changeSubject = {
                userName: 'Iara Nascimento',
                userRole: 'Front End'
            };
            component.updateSubject('botId', 'subjectId', false);
            expect(component['loading']).toBe(false);
            expect(botSubjectServiceSpy.updateSubject).toHaveBeenCalledWith('botId', 'subjectId', mockData);
        });
    });

    it('should test cleanStep', () => {
        botSubjectServiceSpy.updateSubject = jasmine.createSpy('updateSubject').and.returnValue(Observable.of({ attr: 'test' }));
        component.botThirdStep._id = 'testId1';
        component.selected = [
            { id: 'testId2', name: '', userName: '', userRole: '', subjectType: '', subjectChannel: '', subjectArea: '' },
            { id: 'testId3', name: '', userName: '', userRole: '', subjectType: '', subjectChannel: '', subjectArea: '' }
        ];
        component['autosave'] = true;
        component.cleanStep();
        expect(botSubjectServiceSpy.updateSubject).toHaveBeenCalledTimes(2);
    });

    it('should test cleanStep else case', () => {
        component['autosave'] = false;
        component.cleanStep();

    });

    it('should test delete', () => {
        spyOn(component['deleteDraft'], 'emit');
        component.delete();
        expect(component['deleteDraft'].emit).toHaveBeenCalled();
    });

    it('should test goToReview', () => {
        component.botThirdStep._id = 'testId1';
        component.goToReview();
        expect(router.navigateByUrl).toHaveBeenCalledWith('/bot/review-draft/testId1');
    });

    it('should test goBackToAvailable', () => {
        spyOn(component, 'updateSubject');
        component.botThirdStep._id = 'testId1';
        component['autosave'] = true;
        component.goBackToAvailable('testId2');
        expect(component.updateSubject).toHaveBeenCalledWith('testId1', 'testId2', true);
    });

    it('should test goBackToAvailable else case with an array with 1 or more lenght', () => {
        // tslint:disable-next-line:max-line-length
        const selected: BotSubject[] = [{ id: '1234', name: 'Cartão', userName: 'Jonathan', userRole: 'Jonathan', subjectType: 'FAQ', subjectChannel: 'Mobile', subjectArea: 'Cartões' }, { id: '4321', name: 'Cartão', userName: 'Jonathan', userRole: 'Jonathan', subjectType: 'FAQ', subjectChannel: 'Mobile', subjectArea: 'Cartões' }, { id: '1234', name: 'Cartão', userName: 'Jonathan', userRole: 'Jonathan', subjectType: 'FAQ', subjectChannel: 'Mobile', subjectArea: 'Cartões' }];
        component.selected = selected;
        component['autosave'] = false;
        component.goBackToAvailable('1234');
    });

});

Я не ожидал всех этих проблем.Пожалуйста, я много чего перепробовал, помогите мне.

...