mirror of https://github.com/abpframework/abp.git
7 changed files with 481 additions and 7 deletions
@ -0,0 +1,141 @@ |
|||||
|
/* eslint-disable */ |
||||
|
import { describe, it, expect, beforeEach, jest } from '@jest/globals'; |
||||
|
import { FormGroup } from '@angular/forms'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { TestBed } from '@angular/core/testing'; |
||||
|
import { of } from 'rxjs'; |
||||
|
// @ts-ignore - test types are resolved only in the library build context
|
||||
|
import { ToasterService } from '@abp/ng.theme.shared'; |
||||
|
// @ts-ignore - test types are resolved only in the library build context
|
||||
|
import { BlogPostAdminService } from '@abp/ng.cms-kit/proxy'; |
||||
|
import { BlogPostFormService } from '../services'; |
||||
|
|
||||
|
describe('BlogPostFormService', () => { |
||||
|
let service: BlogPostFormService; |
||||
|
let blogPostAdminService: any; |
||||
|
let toasterService: any; |
||||
|
let router: any; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
blogPostAdminService = { |
||||
|
create: jest.fn().mockReturnValue(of({})), |
||||
|
createAndPublish: jest.fn().mockReturnValue(of({})), |
||||
|
createAndSendToReview: jest.fn().mockReturnValue(of({})), |
||||
|
update: jest.fn().mockReturnValue(of({})), |
||||
|
}; |
||||
|
|
||||
|
toasterService = { |
||||
|
success: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
router = { |
||||
|
navigate: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
TestBed.configureTestingModule({ |
||||
|
providers: [ |
||||
|
BlogPostFormService, |
||||
|
{ provide: BlogPostAdminService, useValue: blogPostAdminService }, |
||||
|
{ provide: ToasterService, useValue: toasterService }, |
||||
|
{ provide: Router, useValue: router }, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
service = TestBed.inject(BlogPostFormService); |
||||
|
}); |
||||
|
|
||||
|
function createValidForm(): FormGroup { |
||||
|
// We don't rely on any specific controls, only on form.value and validity.
|
||||
|
return new FormGroup({}); |
||||
|
} |
||||
|
|
||||
|
function createInvalidForm(): FormGroup { |
||||
|
const form = new FormGroup({}); |
||||
|
form.setErrors({ invalid: true }); |
||||
|
return form; |
||||
|
} |
||||
|
|
||||
|
it('should throw when creating with invalid form', () => { |
||||
|
const form = createInvalidForm(); |
||||
|
|
||||
|
expect(() => service.create(form)).toThrowError('Form is invalid'); |
||||
|
}); |
||||
|
|
||||
|
it('should call BlogPostAdminService.create and navigate on create', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.create(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(blogPostAdminService.create).toHaveBeenCalledWith(form.value); |
||||
|
expect(toasterService.success).toHaveBeenCalledWith('AbpUi::SavedSuccessfully'); |
||||
|
expect(router.navigate).toHaveBeenCalledWith(['/cms/blog-posts']); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call BlogPostAdminService.create on createAsDraft', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.createAsDraft(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(blogPostAdminService.create).toHaveBeenCalledWith(form.value); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call BlogPostAdminService.createAndPublish on createAndPublish', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.createAndPublish(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(blogPostAdminService.createAndPublish).toHaveBeenCalledWith(form.value); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call BlogPostAdminService.createAndSendToReview on createAndSendToReview', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.createAndSendToReview(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(blogPostAdminService.createAndSendToReview).toHaveBeenCalledWith(form.value); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should throw when updating with invalid form or missing blog post', () => { |
||||
|
const form = createInvalidForm(); |
||||
|
|
||||
|
expect(() => service.update('id', form, {} as any)).toThrowError( |
||||
|
'Form is invalid or blog post is missing', |
||||
|
); |
||||
|
|
||||
|
const validForm = createValidForm(); |
||||
|
expect(() => service.update('id', validForm, null as any)).toThrowError( |
||||
|
'Form is invalid or blog post is missing', |
||||
|
); |
||||
|
}); |
||||
|
|
||||
|
it('should call BlogPostAdminService.update and navigate on update', done => { |
||||
|
const form = createValidForm(); |
||||
|
const blogPost = { id: '1', title: 't' }; |
||||
|
|
||||
|
service.update('1', form, blogPost).subscribe({ |
||||
|
next: () => { |
||||
|
expect(blogPostAdminService.update).toHaveBeenCalled(); |
||||
|
expect(toasterService.success).toHaveBeenCalledWith('AbpUi::SavedSuccessfully'); |
||||
|
expect(router.navigate).toHaveBeenCalledWith(['/cms/blog-posts']); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,64 @@ |
|||||
|
/* eslint-disable */ |
||||
|
import { describe, it, expect } from '@jest/globals'; |
||||
|
import { Routes } from '@angular/router'; |
||||
|
import { createRoutes } from '../cms-kit-admin.routes'; |
||||
|
import { CmsKitAdminConfigOptions } from '../models'; |
||||
|
|
||||
|
describe('cms-kit-admin routes', () => { |
||||
|
function findRoute(routes: Routes, path: string): any { |
||||
|
for (const route of routes) { |
||||
|
if (route.path === path) { |
||||
|
return route; |
||||
|
} |
||||
|
if (route.children) { |
||||
|
const found = findRoute(route.children, path); |
||||
|
if (found) { |
||||
|
return found; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
it('should create base route with children', () => { |
||||
|
const routes = createRoutes(); |
||||
|
|
||||
|
expect(Array.isArray(routes)).toBe(true); |
||||
|
const root = routes[0]; |
||||
|
expect(root.path).toBe(''); |
||||
|
expect(root.children?.length).toBeGreaterThan(0); |
||||
|
}); |
||||
|
|
||||
|
it('should contain expected admin routes with required policies', () => { |
||||
|
const routes = createRoutes(); |
||||
|
|
||||
|
const comments = findRoute(routes, 'comments'); |
||||
|
const pages = findRoute(routes, 'pages'); |
||||
|
const blogs = findRoute(routes, 'blogs'); |
||||
|
const blogPosts = findRoute(routes, 'blog-posts'); |
||||
|
const menus = findRoute(routes, 'menus'); |
||||
|
const globalResources = findRoute(routes, 'global-resources'); |
||||
|
|
||||
|
expect(comments?.data?.requiredPolicy).toBe('CmsKit.Comments'); |
||||
|
expect(pages?.data?.requiredPolicy).toBe('CmsKit.Pages'); |
||||
|
expect(blogs?.data?.requiredPolicy).toBe('CmsKit.Blogs'); |
||||
|
expect(blogPosts?.data?.requiredPolicy).toBe('CmsKit.BlogPosts'); |
||||
|
expect(menus?.data?.requiredPolicy).toBe('CmsKit.Menus'); |
||||
|
expect(globalResources?.data?.requiredPolicy).toBe('CmsKit.GlobalResources'); |
||||
|
}); |
||||
|
|
||||
|
it('should propagate contributors from config options', () => { |
||||
|
const options: CmsKitAdminConfigOptions = { |
||||
|
entityActionContributors: {}, |
||||
|
entityPropContributors: {}, |
||||
|
toolbarActionContributors: {}, |
||||
|
createFormPropContributors: {}, |
||||
|
editFormPropContributors: {}, |
||||
|
}; |
||||
|
|
||||
|
const routes = createRoutes(options); |
||||
|
const root = routes[0]; |
||||
|
|
||||
|
expect(root.providers).toBeDefined(); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,102 @@ |
|||||
|
/* eslint-disable */ |
||||
|
import { describe, it, expect, beforeEach, jest } from '@jest/globals'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { TestBed } from '@angular/core/testing'; |
||||
|
import { of, Subject } from 'rxjs'; |
||||
|
// @ts-ignore - test types are resolved only in the library build context
|
||||
|
import { ConfigStateService, ListService } from '@abp/ng.core'; |
||||
|
// @ts-ignore - test types are resolved only in the library build context
|
||||
|
import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared'; |
||||
|
// @ts-ignore - proxy module types are resolved only in the library build context
|
||||
|
import { CommentAdminService, CommentGetListInput } from '@abp/ng.cms-kit/proxy'; |
||||
|
import { CommentEntityService } from '../services'; |
||||
|
|
||||
|
describe('CommentEntityService', () => { |
||||
|
let service: CommentEntityService; |
||||
|
let commentAdminService: any; |
||||
|
let toasterService: any; |
||||
|
let confirmationService: any; |
||||
|
let configStateService: any; |
||||
|
let router: any; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
commentAdminService = { |
||||
|
updateApprovalStatus: jest.fn().mockReturnValue(of(void 0)), |
||||
|
delete: jest.fn().mockReturnValue(of(void 0)), |
||||
|
}; |
||||
|
|
||||
|
toasterService = { |
||||
|
success: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
confirmationService = { |
||||
|
warn: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
configStateService = { |
||||
|
getSetting: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
router = { |
||||
|
url: '/cms/comments/123', |
||||
|
}; |
||||
|
|
||||
|
TestBed.configureTestingModule({ |
||||
|
providers: [ |
||||
|
CommentEntityService, |
||||
|
{ provide: CommentAdminService, useValue: commentAdminService }, |
||||
|
{ provide: ToasterService, useValue: toasterService }, |
||||
|
{ provide: ConfirmationService, useValue: confirmationService }, |
||||
|
{ provide: ConfigStateService, useValue: configStateService }, |
||||
|
{ provide: Router, useValue: router }, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
service = TestBed.inject(CommentEntityService); |
||||
|
}); |
||||
|
|
||||
|
it('should return requireApprovement based on setting', () => { |
||||
|
configStateService.getSetting.mockReturnValue('true'); |
||||
|
expect(service.requireApprovement).toBe(true); |
||||
|
|
||||
|
configStateService.getSetting.mockReturnValue('false'); |
||||
|
expect(service.requireApprovement).toBe(false); |
||||
|
}); |
||||
|
|
||||
|
it('should detect comment reply from router url', () => { |
||||
|
expect(service.isCommentReply('123')).toBe(true); |
||||
|
expect(service.isCommentReply('456')).toBe(false); |
||||
|
expect(service.isCommentReply(undefined)).toBe(false); |
||||
|
}); |
||||
|
|
||||
|
it('should update approval status and refresh list', () => { |
||||
|
const list = { |
||||
|
get: jest.fn(), |
||||
|
} as unknown as ListService<any>; |
||||
|
|
||||
|
service.updateApprovalStatus('1', true, list); |
||||
|
|
||||
|
expect(commentAdminService.updateApprovalStatus).toHaveBeenCalledWith('1', { |
||||
|
isApproved: true, |
||||
|
}); |
||||
|
expect(list.get).toHaveBeenCalled(); |
||||
|
expect(toasterService.success).toHaveBeenCalledWith('CmsKit::ApprovedSuccessfully'); |
||||
|
}); |
||||
|
|
||||
|
it('should show confirmation and delete comment when confirmed', () => { |
||||
|
const subject = new Subject<Confirmation.Status>(); |
||||
|
(confirmationService.warn as jest.Mock).mockReturnValue(subject.asObservable()); |
||||
|
|
||||
|
const list = { |
||||
|
get: jest.fn(), |
||||
|
} as unknown as ListService<CommentGetListInput>; |
||||
|
|
||||
|
service.delete('1', list); |
||||
|
|
||||
|
subject.next(Confirmation.Status.confirm); |
||||
|
subject.complete(); |
||||
|
|
||||
|
expect(commentAdminService.delete).toHaveBeenCalledWith('1'); |
||||
|
expect(list.get).toHaveBeenCalled(); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,156 @@ |
|||||
|
/* eslint-disable */ |
||||
|
import { describe, it, expect, beforeEach, jest } from '@jest/globals'; |
||||
|
import { FormGroup } from '@angular/forms'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { TestBed } from '@angular/core/testing'; |
||||
|
import { of } from 'rxjs'; |
||||
|
// @ts-ignore - test types are resolved only in the library build context
|
||||
|
import { ToasterService } from '@abp/ng.theme.shared'; |
||||
|
// @ts-ignore - proxy module types are resolved only in the library build context
|
||||
|
import { PageAdminService, PageDto } from '@abp/ng.cms-kit/proxy'; |
||||
|
import { PageFormService } from '../services'; |
||||
|
|
||||
|
describe('PageFormService', () => { |
||||
|
let service: PageFormService; |
||||
|
let pageAdminService: any; |
||||
|
let toasterService: any; |
||||
|
let router: any; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
pageAdminService = { |
||||
|
create: jest.fn().mockReturnValue(of({})), |
||||
|
update: jest.fn().mockReturnValue(of({})), |
||||
|
setAsHomePage: jest.fn(), |
||||
|
delete: jest.fn(), |
||||
|
get: jest.fn(), |
||||
|
getList: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
toasterService = { |
||||
|
success: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
router = { |
||||
|
navigate: jest.fn(), |
||||
|
}; |
||||
|
|
||||
|
TestBed.configureTestingModule({ |
||||
|
providers: [ |
||||
|
PageFormService, |
||||
|
{ provide: PageAdminService, useValue: pageAdminService }, |
||||
|
{ provide: ToasterService, useValue: toasterService }, |
||||
|
{ provide: Router, useValue: router }, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
service = TestBed.inject(PageFormService); |
||||
|
}); |
||||
|
|
||||
|
function createValidForm(): FormGroup { |
||||
|
return new FormGroup({}); |
||||
|
} |
||||
|
|
||||
|
function createInvalidForm(): FormGroup { |
||||
|
const form = new FormGroup({}); |
||||
|
form.setErrors({ invalid: true }); |
||||
|
return form; |
||||
|
} |
||||
|
|
||||
|
it('should throw when creating with invalid form', () => { |
||||
|
const form = createInvalidForm(); |
||||
|
|
||||
|
expect(() => service.create(form)).toThrowError('Form is invalid'); |
||||
|
}); |
||||
|
|
||||
|
it('should call PageAdminService.create and navigate on create', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.create(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(pageAdminService.create).toHaveBeenCalledWith(form.value); |
||||
|
expect(toasterService.success).toHaveBeenCalledWith('AbpUi::SavedSuccessfully'); |
||||
|
expect(router.navigate).toHaveBeenCalledWith(['/cms/pages']); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call PageAdminService.create on createAsDraft', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.createAsDraft(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(pageAdminService.create).toHaveBeenCalled(); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should call PageAdminService.create on publish', done => { |
||||
|
const form = createValidForm(); |
||||
|
|
||||
|
service.publish(form).subscribe({ |
||||
|
next: () => { |
||||
|
expect(pageAdminService.create).toHaveBeenCalled(); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should throw when updating with invalid form or missing page', () => { |
||||
|
const form = createInvalidForm(); |
||||
|
|
||||
|
expect(() => service.update('id', form, {} as any)).toThrowError( |
||||
|
'Form is invalid or page is missing', |
||||
|
); |
||||
|
|
||||
|
const validForm = createValidForm(); |
||||
|
expect(() => service.update('id', validForm, null as any)).toThrowError( |
||||
|
'Form is invalid or page is missing', |
||||
|
); |
||||
|
}); |
||||
|
|
||||
|
it('should call PageAdminService.update on update', done => { |
||||
|
const form = createValidForm(); |
||||
|
const page = { id: '1', name: 'test', isHomePage: false }; |
||||
|
|
||||
|
service.update('1', form, page).subscribe({ |
||||
|
next: () => { |
||||
|
expect(pageAdminService.update).toHaveBeenCalledWith('1', expect.objectContaining(page)); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should set status Draft on updateAsDraft', done => { |
||||
|
const form = createValidForm(); |
||||
|
const page = { id: '1', name: 'test', isHomePage: false }; |
||||
|
|
||||
|
service.updateAsDraft('1', form, page).subscribe({ |
||||
|
next: () => { |
||||
|
const arg = pageAdminService.update.mock.calls[0][1]; |
||||
|
expect(arg).toMatchObject(page); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should set status Publish on updateAndPublish', done => { |
||||
|
const form = createValidForm(); |
||||
|
const page = { id: '1', name: 'test', isHomePage: false }; |
||||
|
|
||||
|
service.updateAndPublish('1', form, page).subscribe({ |
||||
|
next: () => { |
||||
|
const arg = pageAdminService.update.mock.calls[0][1]; |
||||
|
expect(arg).toMatchObject(page); |
||||
|
done(); |
||||
|
}, |
||||
|
error: err => done(err as any), |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
@ -1 +1,15 @@ |
|||||
import 'jest-preset-angular/setup-jest'; |
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone'; |
||||
|
|
||||
|
setupZoneTestEnv(); |
||||
|
|
||||
|
// Optional: align with core package behavior and provide a stable window.location
|
||||
|
Object.defineProperty(window, 'location', { |
||||
|
value: { |
||||
|
href: 'http://localhost:4200', |
||||
|
origin: 'http://localhost:4200', |
||||
|
pathname: '/', |
||||
|
search: '', |
||||
|
hash: '', |
||||
|
}, |
||||
|
writable: true, |
||||
|
}); |
||||
|
|||||
Loading…
Reference in new issue