fix(aio): correctly intercept links with LinkDirective
This commit is contained in:
parent
fe962f6de7
commit
5815983178
@ -1,7 +1,93 @@
|
|||||||
|
import { async, inject, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { LocationService } from 'app/shared/location.service';
|
||||||
|
import { MockLocationService } from 'testing/location.service';
|
||||||
import { LinkDirective } from './link.directive';
|
import { LinkDirective } from './link.directive';
|
||||||
|
|
||||||
xdescribe('LinkDirective', () => {
|
describe('LinkDirective', () => {
|
||||||
it('should attach to all anchor elements', () => {});
|
|
||||||
it('should bind a property to the "href" attribute', () => {});
|
@Component({
|
||||||
it('should intercept clicks on the element and call `location.go()`', () => {});
|
template: '<a href="{{ url }}">Test Link</a>'
|
||||||
|
})
|
||||||
|
class TestComponent {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
LinkDirective,
|
||||||
|
TestComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: LocationService, useFactory: () => new MockLocationService('initial/url') }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should attach to all anchor elements', () => {
|
||||||
|
const fixture = TestBed.createComponent(TestComponent);
|
||||||
|
const directiveElement = fixture.debugElement.query(By.directive(LinkDirective));
|
||||||
|
expect(directiveElement.name).toEqual('a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should bind a property to the "href" attribute', () => {
|
||||||
|
const fixture = TestBed.createComponent(TestComponent);
|
||||||
|
const directiveElement = fixture.debugElement.query(By.directive(LinkDirective));
|
||||||
|
|
||||||
|
fixture.componentInstance.url = 'test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['href']).toEqual('test/url');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the "target" attribute to "_blank" if the href is absolute, otherwise "_self"', () => {
|
||||||
|
const fixture = TestBed.createComponent(TestComponent);
|
||||||
|
const directiveElement = fixture.debugElement.query(By.directive(LinkDirective));
|
||||||
|
|
||||||
|
fixture.componentInstance.url = 'http://test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_blank');
|
||||||
|
|
||||||
|
fixture.componentInstance.url = 'https://test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_blank');
|
||||||
|
|
||||||
|
fixture.componentInstance.url = 'ftp://test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_blank');
|
||||||
|
|
||||||
|
fixture.componentInstance.url = '//test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_blank');
|
||||||
|
|
||||||
|
fixture.componentInstance.url = 'test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_self');
|
||||||
|
|
||||||
|
fixture.componentInstance.url = '/test/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(directiveElement.properties['target']).toEqual('_self');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should intercept clicks for local urls and call `location.go()`', inject([LocationService], (location: LocationService) => {
|
||||||
|
const fixture = TestBed.createComponent(TestComponent);
|
||||||
|
const directiveElement = fixture.debugElement.query(By.directive(LinkDirective));
|
||||||
|
fixture.componentInstance.url = 'some/local/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
location.go = jasmine.createSpy('Location.go');
|
||||||
|
directiveElement.triggerEventHandler('click', null);
|
||||||
|
expect(location.go).toHaveBeenCalledWith('some/local/url');
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not intercept clicks for absolute urls', inject([LocationService], (location: LocationService) => {
|
||||||
|
const fixture = TestBed.createComponent(TestComponent);
|
||||||
|
const directiveElement = fixture.debugElement.query(By.directive(LinkDirective));
|
||||||
|
fixture.componentInstance.url = 'https://some/absolute/url';
|
||||||
|
fixture.detectChanges();
|
||||||
|
location.go = jasmine.createSpy('Location.go');
|
||||||
|
directiveElement.triggerEventHandler('click', null);
|
||||||
|
expect(location.go).not.toHaveBeenCalled();
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Directive, HostListener, HostBinding, Input } from '@angular/core';
|
import { Directive, HostListener, HostBinding, Input, OnChanges } from '@angular/core';
|
||||||
import { LocationService } from 'app/shared/location.service';
|
import { LocationService } from 'app/shared/location.service';
|
||||||
@Directive({
|
@Directive({
|
||||||
/* tslint:disable-next-line:directive-selector */
|
/* tslint:disable-next-line:directive-selector */
|
||||||
selector: 'a[href]'
|
selector: 'a[href]'
|
||||||
})
|
})
|
||||||
export class LinkDirective {
|
export class LinkDirective implements OnChanges {
|
||||||
|
|
||||||
// We need both these decorators to ensure that we can access
|
// We need both these decorators to ensure that we can access
|
||||||
// the href programmatically, and that it appears as a real
|
// the href programmatically, and that it appears as a real
|
||||||
@ -13,11 +13,27 @@ export class LinkDirective {
|
|||||||
@HostBinding()
|
@HostBinding()
|
||||||
href: string;
|
href: string;
|
||||||
|
|
||||||
|
@HostBinding()
|
||||||
|
target: string;
|
||||||
|
|
||||||
@HostListener('click', ['$event'])
|
@HostListener('click', ['$event'])
|
||||||
onClick($event) {
|
onClick($event) {
|
||||||
this.location.go(this.href);
|
if (this.isAbsolute(this.href)) {
|
||||||
return false;
|
return true;
|
||||||
|
} else {
|
||||||
|
this.location.go(this.href);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isAbsolute(url) {
|
||||||
|
return /^[a-z]+:\/\/|\/\//i.test(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private location: LocationService) { }
|
constructor(private location: LocationService) { }
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
|
this.target = this.isAbsolute(this.href) ? '_blank' : '_self';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user