diff --git a/src/app/settings/board-admin/board-admin.component.ts b/src/app/settings/board-admin/board-admin.component.ts index 9a538ef..dd5111c 100644 --- a/src/app/settings/board-admin/board-admin.component.ts +++ b/src/app/settings/board-admin/board-admin.component.ts @@ -26,41 +26,40 @@ class SelectableUser extends User { @Component({ selector: 'tb-board-admin', templateUrl: './board-admin.component.html', - providers: [ BoardAdminService ], - viewProviders: [ DragulaService ] + providers: [ BoardAdminService ] }) export class BoardAdmin implements OnDestroy { - private displayBoards: Array; private noBoardsMessage: string; - private boardToRemove: Board; - - private userFilter: string; - private statusFilter: string; - private sortFilter: string; private firstRun = true; private subs: Array; + public displayBoards: Array; public users: Array; public boards: Array; public activeUser: User; public modalProps: BoardData; + public boardToRemove: Board; public strings: any; public hasBAUsers = false; public loading = true; public saving = false; + public userFilter: string; + public statusFilter: string; + public sortFilter: string; + public MODAL_ID: string; public MODAL_CONFIRM_ID: string; constructor(private auth: AuthService, public modal: ModalService, - private settings: SettingsService, - private boardService: BoardAdminService, + public settings: SettingsService, + public boardService: BoardAdminService, private notes: NotificationsService, private stringsService: StringsService, - private dragula: DragulaService) { + public dragula: DragulaService) { this.MODAL_ID = 'board-addedit-form'; this.MODAL_CONFIRM_ID = 'board-remove-confirm'; @@ -144,9 +143,9 @@ export class BoardAdmin implements OnDestroy { } this.boardService.editBoard(this.modalProps) - .subscribe((response: ApiResponse) => { - this.handleResponse(response); - }); + .subscribe((response: ApiResponse) => { + this.handleResponse(response); + }); } removeBoard(): void { @@ -395,8 +394,8 @@ export class BoardAdmin implements OnDestroy { private onPropertyEdit(obj: string, prop: string, i: number, value: any): void { - this.modalProps[obj][i][prop] = value; - } + this.modalProps[obj][i][prop] = value; + } private getColor(category: any): string { if (category.default_task_color) { diff --git a/test/app/mocks.ts b/test/app/mocks.ts index 1083b45..7b13a6a 100644 --- a/test/app/mocks.ts +++ b/test/app/mocks.ts @@ -21,9 +21,14 @@ export class DragulaMock { { parentNode: { id: '1' } }, { parentNode: { id: '1' } } ]); + public dragend = { + subscribe: (fn) => { fn(); } + }; find () { - return {}; + return { drake: { + containers: [] + } }; } destroy () {} @@ -34,7 +39,8 @@ export class DragulaMock { } export class BoardServiceMock { - public activeBoardChanged = new BehaviorSubject({ id: 0, name: 'Test', columns: [] }); + public activeBoardChanged = + new BehaviorSubject({ id: 0, name: 'Test', columns: [] }); getBoards () { return new BehaviorSubject({ @@ -51,3 +57,21 @@ export class BoardServiceMock { } } +export class SettingsServiceMock { + public usersChanged = new BehaviorSubject([{ security_level: 2 }]); + + public boardsChanged = new BehaviorSubject([ + { columns: [{ position: 3 }, { position: 2 }] } + ]); + + updateBoards () { } + + updateActions () { } +} + +export class AuthServiceMock { + public userChanged = new BehaviorSubject({ security_level: 1 }); + + public userOptions = { show_animations: false }; +} + diff --git a/test/app/settings/board-admin/board-admin.component.spec.ts b/test/app/settings/board-admin/board-admin.component.spec.ts index c8c6736..bad3ac5 100644 --- a/test/app/settings/board-admin/board-admin.component.spec.ts +++ b/test/app/settings/board-admin/board-admin.component.spec.ts @@ -2,7 +2,6 @@ import { TestBed, ComponentFixture } from '@angular/core/testing' import { RouterTestingModule } from '@angular/router/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing'; import { FormsModule } from '@angular/forms'; -import { DomSanitizer } from '@angular/platform-browser'; import { DragulaService } from 'ng2-dragula/ng2-dragula'; import { DragulaModule } from 'ng2-dragula/ng2-dragula'; @@ -16,14 +15,22 @@ import { StringsService } from '../../../../src/app/shared/services'; import { SettingsService } from '../../../../src/app/settings/settings.service'; -import { BoardAdminService } from '../../../../src/app/settings/board-admin/board-admin.service'; +import { + BoardAdminService +} from '../../../../src/app/settings/board-admin/board-admin.service'; +import { Board } from '../../../../src/app/shared/models'; +import { DragulaMock, SettingsServiceMock, AuthServiceMock } from '../../mocks'; -import { BoardAdmin } from '../../../../src/app/settings/board-admin/board-admin.component'; +import { + BoardAdmin +} from '../../../../src/app/settings/board-admin/board-admin.component'; describe('BoardAdmin', () => { let component: BoardAdmin, fixture: ComponentFixture; + const getPrivateFunction = name => component[name].bind(component); + beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -41,9 +48,10 @@ describe('BoardAdmin', () => { ModalService, NotificationsService, StringsService, - SettingsService, BoardAdminService, - DragulaService + { provide: DragulaService, useClass: DragulaMock }, + { provide: SettingsService, useClass: SettingsServiceMock }, + { provide: AuthService, useClass: AuthServiceMock } ] }).compileComponents(); }); @@ -58,10 +66,237 @@ describe('BoardAdmin', () => { expect(component).toBeTruthy(); }); - // it('calls a service to add a board', () => { - // component.modalProps.title = 'Add'; - // - // }); + it('sets up drag and drop during ngAfterContentInit', () => { + component.modalProps = { columns: [{ position: '' }] }; + component.ngAfterContentInit(); + + expect((component.dragula).opts.moves).toEqual(jasmine.any(Function)); + expect(component.modalProps.columns[0].position).toEqual('0'); + + const test = (component.dragula).opts.moves(null, null, { + classList: { contains: () => false } + }); + expect(test).toEqual(false); + }); + + it('validates a board before saving', () => { + component.modalProps = { columns: [] }; + component.addEditBoard(); + + expect(component.saving).toEqual(false); + }); + + it('calls a service to add a board', () => { + component.modalProps = { + title: 'Add', + name: 'Test', + columns: [{}] + }; + component.users = [{ selected: true }]; + + let called = false; + + (component.boardService).addBoard = () => { + return { subscribe: fn => { + const board = new Board(); + fn({ status: 'success', alerts: [{}], data: [{}, [board]] }); + called = true; + } }; + }; + + component.addEditBoard(); + expect(called).toEqual(true); + }); + + it('calls a service to edit a board', () => { + component.modalProps = { + title: '', + name: '', + columns: [{}] + }; + component.users = [{}]; + + let called = false; + + (component.boardService).editBoard = () => { + return { subscribe: fn => { + const board = new Board(); + fn({ status: 'success', alerts: [{}], data: [{}, [board]] }); + called = true; + } }; + }; + + component.addEditBoard(); + component.modalProps.name = 'Test'; + expect(called).toEqual(false); + + component.addEditBoard(); + expect(called).toEqual(true); + }); + + it('calls a service to remove a board', () => { + let called = false; + + (component.boardService).removeBoard = () => { + return { subscribe: fn => fn({ alerts: [], data: [{}, []] }) }; + }; + (component.settings).getActions = () => { + return { subscribe: fn => { + fn({ alerts: [], data: [{}, []] }); + called = true; + } }; + }; + + component.boardToRemove = { id: 1 }; + component.removeBoard(); + + expect(called).toEqual(true); + }); + + it('calls a service to toggle a board\'s status', () => { + let called = false; + + (component.boardService).editBoard = () => { + return { subscribe: fn => { + const board = new Board(); + fn({ status: 'success', alerts: [{}], data: [{}, [board]] }); + called = true; + } }; + }; + + component.toggleBoardStatus({ + id: 1, name: 'Name', is_active: true, columns: [], + categories: [], issue_trackers: [], users: [] + }); + + expect(called).toEqual(true); + }); + + it('can filter the list of boards by user', () => { + component.boards = [ + { users: [{ id: 1 }] } + ]; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(1); + + component.userFilter = '1'; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(1); + + component.userFilter = '2'; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(0); + }); + + it('can filter the list of boards by status', () => { + component.boards = [ + { is_active: true, users: [] } + ]; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(1); + + component.statusFilter = '1'; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(1); + + component.statusFilter = '0'; + + component.filterBoards(); + expect(component.displayBoards.length).toEqual(0); + }); + + it('sorts the list of boards after filtering', () => { + component.boards = [ + { id: 1, name: 'last' }, + { id: 2, name: 'first' } + ]; + component.sortFilter = 'name-asc'; + + component.filterBoards(); + expect(component.displayBoards[0].name).toEqual('first'); + + component.sortFilter = 'name-desc'; + + component.filterBoards(); + expect(component.displayBoards[0].name).toEqual('last'); + + component.sortFilter = 'id-asc'; + + component.filterBoards(); + expect(component.displayBoards[0].id).toEqual(1); + + component.sortFilter = 'id-desc'; + + component.filterBoards(); + expect(component.displayBoards[0].id).toEqual(2); + }); + + it('can stop enter key events from bubbling', () => { + let called = false; + + component.cancelEnterKey({ stopPropagation: () => called = true }); + + expect(called).toEqual(true); + }); + + it('can get a property value for the modal', () => { + const getPropertyValue = getPrivateFunction('getPropertyValue'); + component.modalProps = { columns: [{ name: 'test' }] }; + + const actual = getPropertyValue('columns', 'name', 0); + expect(actual).toEqual('test'); + }); + + it('handles a property change', () => { + const onPropertyEdit = getPrivateFunction('onPropertyEdit'); + component.modalProps = { columns: [{ name: 'test' }] }; + + onPropertyEdit('columns', 'name', 0, 'changed'); + expect(component.modalProps.columns[0].name).toEqual('changed'); + }); + + it('gets a category color', () => { + const getColor = getPrivateFunction('getColor'); + let actual = getColor({ default_task_color: 'red' }); + + expect(actual).toEqual('red'); + + actual = getColor({ defaultColor: 'orange' }); + expect(actual).toEqual('orange'); + }); + + it('can set a category color', () => { + const setCategoryColor = getPrivateFunction('setCategoryColor'); + component.modalProps = { categories: [{}] }; + + setCategoryColor('purple', 0); + const actual = component.modalProps.categories[0].default_task_color; + expect(actual).toEqual('purple'); + }); + + it('can show a modal', () => { + const showModal = getPrivateFunction('showModal'); + + component.users = [{ selected: true }]; + showModal('Add'); + + expect((component.users[0]).selected).toEqual(false); + + showModal('Edit', new Board()); + }); + + it('can show a confirmation modal', () => { + const showConfirmModal = getPrivateFunction('showConfirmModal'); + + showConfirmModal({ works: true }); + + expect((component.boardToRemove).works).toEqual(true); + }); }); diff --git a/test/app/settings/board-admin/board-admin.service.spec.ts b/test/app/settings/board-admin/board-admin.service.spec.ts index e69de29..2cd30a0 100644 --- a/test/app/settings/board-admin/board-admin.service.spec.ts +++ b/test/app/settings/board-admin/board-admin.service.spec.ts @@ -0,0 +1,55 @@ +import { TestBed, getTestBed } from '@angular/core/testing' +import { + HttpClientTestingModule, + HttpTestingController +} from '@angular/common/http/testing'; + +import { + BoardAdminService +} from '../../../../src/app/settings/board-admin/board-admin.service'; + +describe('BoardAdminService', () => { + let injector: TestBed; + let service: BoardAdminService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [BoardAdminService] + }); + + injector = getTestBed(); + service = injector.get(BoardAdminService); + httpMock = injector.get(HttpTestingController); + }); + + afterEach(() => { + httpMock.verify(); + }) + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('adds a board', () => { + service.addBoard({}).subscribe(response => { + expect(response.data.length).toEqual(0); + }); + + testCall('api/boards', 'POST'); + }); + + const testCall = (url, method, isError = false) => { + const req = httpMock.expectOne(url); + expect(req.request.method).toEqual(method); + + if (isError) { + req.flush({ alerts: [{}] }, { status: 500, statusText: '' }); + } else { + req.flush({ data: [] }); + } + } + +}); +