mirror of https://github.com/abpframework/abp
commit
b3d4d279d9
@ -0,0 +1,191 @@
|
||||
import { SpectatorDirective, createDirectiveFactory } from '@ngneat/spectator/jest';
|
||||
import { ForDirective } from '../directives/for.directive';
|
||||
import { uuid } from '../utils';
|
||||
|
||||
describe('ForDirective', () => {
|
||||
let spectator: SpectatorDirective<ForDirective>;
|
||||
let directive: ForDirective;
|
||||
const items = [0, 1, 2, 3, 4, 5];
|
||||
const createDirective = createDirectiveFactory({
|
||||
directive: ForDirective,
|
||||
});
|
||||
|
||||
describe('basic', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective('<ul><li *abpFor="let item of items">{{ item }}</li></ul>', {
|
||||
hostProps: { items },
|
||||
});
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should be created', () => {
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should be iterated', () => {
|
||||
const elements = spectator.queryAll('li');
|
||||
|
||||
expect(elements[3]).toHaveText('3');
|
||||
expect(elements).toHaveLength(6);
|
||||
});
|
||||
|
||||
test('should sync the DOM when change items', () => {
|
||||
(spectator.hostComponent as any).items = [10, 11, 12];
|
||||
spectator.detectChanges();
|
||||
const elements = spectator.queryAll('li');
|
||||
|
||||
expect(elements[1]).toHaveText('11');
|
||||
expect(elements).toHaveLength(3);
|
||||
});
|
||||
|
||||
test('should sync the DOM when add an item', () => {
|
||||
(spectator.hostComponent as any).items = [...items, 6];
|
||||
spectator.detectChanges();
|
||||
const elements = spectator.queryAll('li');
|
||||
|
||||
expect(elements[6]).toHaveText('6');
|
||||
expect(elements).toHaveLength(7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackBy', () => {
|
||||
const trackByFn = (_, item) => item;
|
||||
beforeEach(() => {
|
||||
spectator = createDirective('<ul><li *abpFor="let item of items; trackBy: trackByFn">{{ item }}</li></ul>', {
|
||||
hostProps: { items, trackByFn },
|
||||
});
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should be setted the trackBy', () => {
|
||||
expect(directive.trackBy).toEqual(trackByFn);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with basic order', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
`<ul>
|
||||
<li
|
||||
*abpFor="let item of [3,6,2];
|
||||
orderDir: 'ASC'">
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>`,
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should order by asc', () => {
|
||||
const elements = spectator.queryAll('li');
|
||||
expect(elements.map(el => el.textContent.trim())).toEqual(['2', '3', '6']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with order', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
`<ul>
|
||||
<li
|
||||
*abpFor="let item of [{value: 3}, {value: 6}, {value: 2}];
|
||||
orderBy: 'value';
|
||||
orderDir: orderDir">
|
||||
{{ item.value }}
|
||||
</li>
|
||||
</ul>`,
|
||||
{
|
||||
hostProps: { orderDir: 'ASC' },
|
||||
},
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should order by asc', () => {
|
||||
const elements = spectator.queryAll('li');
|
||||
expect(elements.map(el => el.textContent.trim())).toEqual(['2', '3', '6']);
|
||||
});
|
||||
|
||||
test('should order by desc', () => {
|
||||
(spectator.hostComponent as any).orderDir = 'DESC';
|
||||
spectator.detectChanges();
|
||||
|
||||
const elements = spectator.queryAll('li');
|
||||
expect(elements.map(el => el.textContent.trim())).toEqual(['6', '3', '2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with filter', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
`<ul>
|
||||
<li
|
||||
*abpFor="let item of [{value: 'test'}, {value: 'abp'}, {value: 'volo'}];
|
||||
filterBy: 'value';
|
||||
filterVal: filterVal">
|
||||
{{ item.value }}
|
||||
</li>
|
||||
</ul>`,
|
||||
{
|
||||
hostProps: { filterVal: '' },
|
||||
},
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should not filter when filterVal is empty,', () => {
|
||||
const elements = spectator.queryAll('li');
|
||||
expect(elements.map(el => el.textContent.trim())).toEqual(['test', 'abp', 'volo']);
|
||||
});
|
||||
|
||||
test('should be filtered', () => {
|
||||
(spectator.hostComponent as any).filterVal = 'volo';
|
||||
spectator.detectChanges();
|
||||
|
||||
expect(spectator.query('li')).toHaveText('volo');
|
||||
});
|
||||
|
||||
test('should not show an element when filter value not match to any text', () => {
|
||||
(spectator.hostComponent as any).filterVal = 'volos';
|
||||
spectator.detectChanges();
|
||||
|
||||
const elements = spectator.queryAll('li');
|
||||
expect(elements).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with empty ref', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
`<ul>
|
||||
<li
|
||||
*abpFor="let item of items;
|
||||
emptyRef: empty">
|
||||
{{ item.value }}
|
||||
</li>
|
||||
|
||||
<ng-template #empty>No records found</ng-template>
|
||||
</ul>`,
|
||||
{
|
||||
hostProps: { items: [] },
|
||||
},
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
test('should display the empty ref', () => {
|
||||
expect(spectator.query('ul')).toHaveText('No records found');
|
||||
expect(spectator.queryAll('li')).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('should not display the empty ref', () => {
|
||||
expect(spectator.query('ul')).toHaveText('No records found');
|
||||
expect(spectator.queryAll('li')).toHaveLength(0);
|
||||
|
||||
(spectator.hostComponent as any).items = [0];
|
||||
spectator.detectChanges();
|
||||
|
||||
expect(spectator.query('ul')).not.toHaveText('No records found');
|
||||
expect(spectator.queryAll('li')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,74 @@
|
||||
import { createServiceFactory, SpectatorService, SpyObject } from '@ngneat/spectator/jest';
|
||||
import { Session } from '../models/session';
|
||||
import { ProfileService } from '../services';
|
||||
import { ProfileState } from '../states';
|
||||
import { GetAppConfiguration } from '../actions/config.actions';
|
||||
import { of } from 'rxjs';
|
||||
import { Profile } from '../models/profile';
|
||||
|
||||
export class DummyClass {}
|
||||
|
||||
export const PROFILE_STATE_DATA = {
|
||||
profile: { userName: 'admin', email: 'info@abp.io', name: 'Admin' },
|
||||
} as Profile.State;
|
||||
|
||||
describe('ProfileState', () => {
|
||||
let spectator: SpectatorService<DummyClass>;
|
||||
let state: ProfileState;
|
||||
let profileService: SpyObject<ProfileService>;
|
||||
let patchedData;
|
||||
const patchState = jest.fn(data => (patchedData = data));
|
||||
|
||||
const createService = createServiceFactory({
|
||||
service: DummyClass,
|
||||
mocks: [ProfileService],
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
spectator = createService();
|
||||
profileService = spectator.get(ProfileService);
|
||||
state = new ProfileState(profileService);
|
||||
});
|
||||
|
||||
describe('#getProfile', () => {
|
||||
it('should return the current language', () => {
|
||||
expect(ProfileState.getProfile(PROFILE_STATE_DATA)).toEqual(PROFILE_STATE_DATA.profile);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#GetProfile', () => {
|
||||
it('should call the profile service get method and update the state', () => {
|
||||
const mockData = { userName: 'test', email: 'test@abp.io' };
|
||||
const spy = jest.spyOn(profileService, 'get');
|
||||
spy.mockReturnValue(of(mockData as any));
|
||||
|
||||
state.profileGet({ patchState } as any).subscribe();
|
||||
|
||||
expect(patchedData).toEqual({ profile: mockData });
|
||||
});
|
||||
});
|
||||
|
||||
describe('#UpdateProfile', () => {
|
||||
it('should call the profile service update method and update the state', () => {
|
||||
const mockData = { userName: 'test2', email: 'test@abp.io' };
|
||||
const spy = jest.spyOn(profileService, 'update');
|
||||
spy.mockReturnValue(of(mockData as any));
|
||||
|
||||
state.profileUpdate({ patchState } as any, { payload: mockData as any }).subscribe();
|
||||
|
||||
expect(patchedData).toEqual({ profile: mockData });
|
||||
});
|
||||
});
|
||||
|
||||
describe('#ChangePassword', () => {
|
||||
it('should call the profile service changePassword method', () => {
|
||||
const mockData = { currentPassword: 'test123', newPassword: 'test123' };
|
||||
const spy = jest.spyOn(profileService, 'changePassword');
|
||||
spy.mockReturnValue(of(null));
|
||||
|
||||
state.changePassword(null, { payload: mockData }).subscribe();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(mockData, true);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,70 @@
|
||||
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
|
||||
import { Session } from '../models/session';
|
||||
import { LocalizationService } from '../services';
|
||||
import { SessionState } from '../states';
|
||||
import { GetAppConfiguration } from '../actions/config.actions';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
export class DummyClass {}
|
||||
|
||||
export const SESSION_STATE_DATA = {
|
||||
language: 'tr',
|
||||
tenant: { id: 'd5692aef-2ac6-49cd-9f3e-394c0bd4f8b3', name: 'Test' },
|
||||
} as Session.State;
|
||||
|
||||
describe('SessionState', () => {
|
||||
let spectator: SpectatorService<DummyClass>;
|
||||
let state: SessionState;
|
||||
|
||||
const createService = createServiceFactory({
|
||||
service: DummyClass,
|
||||
mocks: [LocalizationService],
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
spectator = createService();
|
||||
state = new SessionState(spectator.get(LocalizationService));
|
||||
});
|
||||
|
||||
describe('#getLanguage', () => {
|
||||
it('should return the current language', () => {
|
||||
expect(SessionState.getLanguage(SESSION_STATE_DATA)).toEqual(SESSION_STATE_DATA.language);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getTenant', () => {
|
||||
it('should return the tenant object', () => {
|
||||
expect(SessionState.getTenant(SESSION_STATE_DATA)).toEqual(SESSION_STATE_DATA.tenant);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#SetLanguage', () => {
|
||||
it('should set the language and dispatch the GetAppConfiguration action', () => {
|
||||
let patchedData;
|
||||
let dispatchedData;
|
||||
const patchState = jest.fn(data => (patchedData = data));
|
||||
const dispatch = jest.fn(action => {
|
||||
dispatchedData = action;
|
||||
return of({});
|
||||
});
|
||||
const spy = jest.spyOn(spectator.get(LocalizationService), 'registerLocale');
|
||||
|
||||
state.setLanguage({ patchState, dispatch } as any, { payload: 'en' }).subscribe();
|
||||
|
||||
expect(patchedData).toEqual({ language: 'en' });
|
||||
expect(dispatchedData instanceof GetAppConfiguration).toBeTruthy();
|
||||
expect(spy).toHaveBeenCalledWith('en');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setTenantId', () => {
|
||||
it('should set the tenant', () => {
|
||||
let patchedData;
|
||||
const patchState = jest.fn(data => (patchedData = data));
|
||||
const testTenant = { id: '54ae02ba-9289-4c1b-8521-0ea437756288', name: 'Test Tenant' };
|
||||
state.setTenant({ patchState } as any, { payload: testTenant });
|
||||
|
||||
expect(patchedData).toEqual({ tenant: testTenant });
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,128 @@
|
||||
import { SpectatorDirective, createDirectiveFactory } from '@ngneat/spectator/jest';
|
||||
import { VisibilityDirective } from '../directives/visibility.directive';
|
||||
|
||||
describe('VisibilityDirective', () => {
|
||||
let spectator: SpectatorDirective<VisibilityDirective>;
|
||||
let directive: VisibilityDirective;
|
||||
const createDirective = createDirectiveFactory({
|
||||
directive: VisibilityDirective,
|
||||
});
|
||||
|
||||
describe('without mutation observer and without content', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective('<div [abpVisibility] [mutationObserverEnabled]="false"></div>');
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be removed', done => {
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('div')).toBeFalsy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('without mutation observer and with content', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
'<div [abpVisibility] [mutationObserverEnabled]="false"><p id="content">Content</p></div>',
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should not removed', done => {
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('div')).toBeTruthy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('without mutation observer and with focused element', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
'<div id="main" [abpVisibility]="container" [mutationObserverEnabled]="false"></div><div #container><p id="content">Content</p></div>',
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should not removed', done => {
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('#main')).toBeTruthy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('without content and with focused element', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
'<div id="main" [abpVisibility]="container" [mutationObserverEnabled]="false"></div><div #container></div>',
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should be removed', done => {
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('#main')).toBeFalsy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with mutation observer and with content', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective('<div [abpVisibility]><div id="content">Content</div></div>');
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should remove the main div element when content removed', done => {
|
||||
spectator.query('#content').remove();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('div')).toBeFalsy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should not remove the main div element', done => {
|
||||
spectator.query('div').appendChild(document.createElement('div'));
|
||||
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('div')).toBeTruthy();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with mutation observer and with focused element', () => {
|
||||
beforeEach(() => {
|
||||
spectator = createDirective(
|
||||
'<div id="main" [abpVisibility]="container"></div><div #container><p id="content">Content</p></div>',
|
||||
);
|
||||
directive = spectator.directive;
|
||||
});
|
||||
|
||||
it('should remove the main div element when content removed', done => {
|
||||
spectator.query('#content').remove();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('#main')).toBeFalsy();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should not remove the main div element', done => {
|
||||
spectator.query('#content').appendChild(document.createElement('div'));
|
||||
|
||||
setTimeout(() => {
|
||||
expect(spectator.query('#main')).toBeTruthy();
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,16 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { GetRoles } from '../actions/identity.actions';
|
||||
import { Identity } from '../models/identity';
|
||||
import { IdentityState } from '../states/identity.state';
|
||||
|
||||
@Injectable()
|
||||
export class RoleResolver implements Resolve<Identity.State> {
|
||||
constructor(private store: Store) {}
|
||||
|
||||
resolve() {
|
||||
const roles = this.store.selectSnapshot(IdentityState.getRoles);
|
||||
return roles && roles.length ? null : this.store.dispatch(new GetRoles());
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { GetUsers } from '../actions/identity.actions';
|
||||
import { Identity } from '../models/identity';
|
||||
import { IdentityState } from '../states/identity.state';
|
||||
|
||||
@Injectable()
|
||||
export class UserResolver implements Resolve<Identity.State> {
|
||||
constructor(private store: Store) {}
|
||||
|
||||
resolve() {
|
||||
const users = this.store.selectSnapshot(IdentityState.getUsers);
|
||||
return users && users.length ? null : this.store.dispatch(new GetUsers());
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './tenants.resolver';
|
@ -1,16 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { GetTenants } from '../actions/tenant-management.actions';
|
||||
import { TenantManagement } from '../models/tenant-management';
|
||||
import { TenantManagementState } from '../states/tenant-management.state';
|
||||
|
||||
@Injectable()
|
||||
export class TenantsResolver implements Resolve<TenantManagement.State> {
|
||||
constructor(private store: Store) {}
|
||||
|
||||
resolve() {
|
||||
const data = this.store.selectSnapshot(TenantManagementState.get);
|
||||
return data && data.length ? null : this.store.dispatch(new GetTenants());
|
||||
}
|
||||
}
|
Loading…
Reference in new issue