Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling external page redirection on unit testing - jasmine with code coverage

writing the unit testing for angular application, login mechanism works on single sing on concept, page will redirect to external url and set the cookie value for the login success (based on cookie setting local storage).

while testing that scenario browser redirects to external page and stops the unit test execution. Currently while doing the unit test commented the redirection and testing the remaining test cases.

While deploying to live again i have to uncomment the redirect code.

How can I handle this scenario in jasmine?

    @Injectable()
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        private location: Location
    ) { }

    canActivate(): boolean {
        if (!localStorage.getItem('API_TOKEN')) {
            this.redirectTOLogin();
            return false;
        } else {
            return true;
        }
    }

    redirectTOLogin() {
        window.location.href = environment.appLoginUrl + environment.appUrl;
    }
}

spec.ts

    describe('Logged in guard should', () => {
    let loggedInGuard: AuthGuard;
    const router = {
        navigate: jasmine.createSpy('navigate')
    };

    // async beforeEach
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [FormsModule, CommonModule],
            providers: [AuthGuard, Location, { provide: LocationStrategy, useClass: PathLocationStrategy },
                { provide: APP_BASE_HREF, useValue: '/' },
                { provide: Router, useValue: router }
            ]
        })
            .compileComponents(); // compile template and css
    }));

    // synchronous beforeEach
    beforeEach(() => {
        loggedInGuard = TestBed.get(AuthGuard);
    });

    it('be able to hit route when user is logged in', () => {
        localStorage.setItem('API_TOKEN', 'fgsdhfhg4359854dsfsdf#@dfg4545nvnsjfjkh');
        expect(loggedInGuard.canActivate()).toBe(true);
    });

    it('not be able to hit route when user is not logged in', () => {
        localStorage.removeItem('API_TOKEN');
        spyOn(loggedInGuard, 'redirectTOLogin');
        expect(loggedInGuard.redirectTOLogin).toHaveBeenCalled();
    });
});
like image 360
Govinda raj Avatar asked Aug 14 '26 21:08

Govinda raj


1 Answers

I'd propose to outsource the window call into a separate function, and in the test then create a spy to check if it has been called!

What you want to test in this case is only if the redirect is triggered, not if the native browser functionality is actually working!

The spy jasmine creates then l prevents the actual execution of the function in the test!

redirect() {
   window.location.href = 'logindomainname.com?ReturnUrl=http://localhost:4200';
}

// in your test then...
spyOn(component, 'redirect');
//...
expect(component.redirect). toHaveBeenCalled();

EDIT:

In your first test case, I do not see a problem, this should be working and it should not redirect, as logic is not intended to.

In your second test case though, it should just fail, due to the fact that you're not calling canActivate at all. So the following should succeed:

it('not be able to hit route when user is not logged in', () => {
    localStorage.removeItem('API_TOKEN');
    spyOn(loggedInGuard, 'redirectTOLogin');

    expect(loggedInGuard.canActivate()).toBe(false);
    expect(loggedInGuard.redirectTOLogin).toHaveBeenCalled();
});

This will call canActivate, which should return false and calls the redirectTOLogin function before returning false, which is then recognized by your spy.

like image 106
OClyde Avatar answered Aug 16 '26 21:08

OClyde



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!