Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: unit test formation with Jest #729

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c8d2c75
chore/ unit test formation with Jest
yannick-aneo Oct 12, 2023
c5cbb9c
docs: add config documentation
yannick-aneo Oct 13, 2023
48d8217
Merge branch 'main' of https://github.com/aneoconsulting/ArmoniK.Admi…
yannick-aneo Oct 13, 2023
5232f83
Update unit_test_formation.md
yannick-aneo Oct 13, 2023
8060bb3
docs: documentation about setting up and creating unit test for a sim…
yannick-aneo Oct 16, 2023
12f8fcd
Write documentation on setting up tests for service with dependencies
yannick-aneo Oct 16, 2023
af71c9d
update unit test formation
yannick-aneo Oct 16, 2023
8bd2103
finish first version of unit test formation in ArmoniK
yannick-aneo Oct 17, 2023
d34dc1a
Merge branch 'main' of https://github.com/aneoconsulting/ArmoniK.Admi…
yannick-aneo Oct 17, 2023
094ba8e
fix: http to https in tests (#745)
fdewas-aneo Oct 17, 2023
4553330
Merge branch 'yannick-aneo-patch-1' of https://github.com/aneoconsult…
yannick-aneo Oct 17, 2023
8ff7645
test: dashboard storage service (#737)
fdewas-aneo Oct 17, 2023
f8b24b2
chore: fix sort unreliability (#715)
fdewas-aneo Oct 18, 2023
95dbad6
feat: lock and unlock columns for tables (#742)
fdewas-aneo Oct 18, 2023
b604d98
chore: tests for application grpc services (#718)
fdewas-aneo Oct 18, 2023
2831ad5
docs: v1 unit test formation
yannick-aneo Oct 18, 2023
f180aed
chore: tested applications index service (#710)
fdewas-aneo Oct 19, 2023
87f4e58
test: sessions filters service (#748)
fdewas-aneo Oct 20, 2023
0970360
test: dashboard index service (#736)
fdewas-aneo Oct 20, 2023
6fe4550
tests for columns-modify-dialog component and some refactor
fdewas-aneo Sep 28, 2023
b84670b
clarified tests descriptions
fdewas-aneo Sep 28, 2023
fd26193
update names in filter stream
fdewas-aneo Oct 9, 2023
da6eec4
Merge pull request #646 from aneoconsulting/tests-columns-modify-dial…
GunaDinesh Nov 28, 2023
353f001
chore: tests for form name line component
fdewas-aneo Oct 12, 2023
8df46d9
Merge pull request #724 from aneoconsulting/form-name-line-component-…
GunaDinesh Nov 28, 2023
c7630d0
chore: tests for add-line-dialog component
fdewas-aneo Oct 12, 2023
26024b8
Merge pull request #725 from aneoconsulting/add-line-dialog-component…
GunaDinesh Nov 28, 2023
25c58e7
chore: tests for add statuses group dialog component
fdewas-aneo Oct 12, 2023
a9bbc06
Merge pull request #726 from aneoconsulting/add-statuses-group-dialog…
GunaDinesh Nov 28, 2023
84418e5
chore: tests for edit status group dialog component
fdewas-aneo Oct 12, 2023
5153a65
Merge pull request #728 from aneoconsulting/edit-status-group-dialog-…
GunaDinesh Nov 28, 2023
1c16710
Initialize applications tests
fdewas-aneo Sep 13, 2023
37a9ed2
added some mocks
fdewas-aneo Oct 10, 2023
1045c31
added test
fdewas-aneo Oct 11, 2023
fa25592
added all tests for application component
fdewas-aneo Oct 11, 2023
a54f4ab
Merge pull request #587 from aneoconsulting/applications-tests
GunaDinesh Nov 28, 2023
a45ae86
Merge branch 'yannick-aneo-patch-1' of https://github.com/aneoconsult…
GunaDinesh Nov 28, 2023
00fe687
docs: syntax corrections
GunaDinesh Nov 28, 2023
65d4f26
chore/ unit test formation with Jest
yannick-aneo Oct 12, 2023
f74343c
docs: add config documentation
yannick-aneo Oct 13, 2023
9a41182
Update unit_test_formation.md
yannick-aneo Oct 13, 2023
4ebce4d
docs: documentation about setting up and creating unit test for a sim…
yannick-aneo Oct 16, 2023
9e173d6
Write documentation on setting up tests for service with dependencies
yannick-aneo Oct 16, 2023
82741de
update unit test formation
yannick-aneo Oct 16, 2023
13a552c
finish first version of unit test formation in ArmoniK
yannick-aneo Oct 17, 2023
758ddc8
docs: v1 unit test formation
yannick-aneo Oct 18, 2023
1d30372
docs: syntax corrections
GunaDinesh Nov 28, 2023
d5f9314
Merge branch 'yannick-aneo-patch-1' of https://github.com/aneoconsult…
GunaDinesh Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
422 changes: 422 additions & 0 deletions src/app/applications/index.component.spec.ts

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions src/app/applications/index.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ import { ApplicationRaw, ApplicationRawColumnKey, ApplicationRawFieldKey, Applic
[columnsLabels]="columnsLabels()"
[displayedColumns]="displayedColumns"
[availableColumns]="availableColumns"
[lockColumns]="lockColumns"
(refresh)="onRefresh()"
(intervalValueChange)="onIntervalValueChange($event)"
(displayedColumnsChange)="onColumnsChange($event)"
(resetColumns)="onColumnsReset()"
(resetFilters)="onFiltersReset()"
(lockColumnsChange)="onLockColumnsChange()"
>
<ng-container extra-menu-items>
<button mat-menu-item (click)="personalizeTasksByStatus()">
Expand All @@ -85,7 +87,7 @@ import { ApplicationRaw, ApplicationRawColumnKey, ApplicationRawFieldKey, Applic
</mat-toolbar>

<app-table-container>
<table mat-table matSort [matSortActive]="options.sort.active" matSortDisableClear [matSortDirection]="options.sort.direction" [dataSource]="data" cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="onDrop($event)">
<table mat-table matSort [matSortActive]="options.sort.active" matSortDisableClear [matSortDirection]="options.sort.direction" [dataSource]="data" cdkDropList cdkDropListOrientation="horizontal" [cdkDropListDisabled]="lockColumns" (cdkDropListDropped)="onDrop($event)">

<ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
<!-- Header -->
Expand Down Expand Up @@ -210,6 +212,7 @@ export class IndexComponent implements OnInit, AfterViewInit, OnDestroy {

displayedColumns: ApplicationRawColumnKey[] = [];
availableColumns: ApplicationRawColumnKey[] = [];
lockColumns: boolean = false;

isLoading = true;
data: ApplicationRaw[] = [];
Expand Down Expand Up @@ -243,6 +246,7 @@ export class IndexComponent implements OnInit, AfterViewInit, OnDestroy {
ngOnInit(): void {
this.displayedColumns = this._applicationsIndexService.restoreColumns();
this.availableColumns = this._applicationsIndexService.availableColumns;
this.lockColumns = this._applicationsIndexService.restoreLockColumns();

this.options = this._applicationsIndexService.restoreOptions();

Expand Down Expand Up @@ -357,7 +361,7 @@ export class IndexComponent implements OnInit, AfterViewInit, OnDestroy {
}

onColumnsChange(data: ApplicationRawColumnKey[]) {
this.displayedColumns = [...data];
this.displayedColumns = data;

this._applicationsIndexService.saveColumns(data);
}
Expand All @@ -380,6 +384,11 @@ export class IndexComponent implements OnInit, AfterViewInit, OnDestroy {
this.refresh.next();
}

onLockColumnsChange() {
this.lockColumns = !this.lockColumns;
this._applicationsIndexService.saveLockColumns(this.lockColumns);
}

autoRefreshTooltip() {
return this._autoRefreshService.autoRefreshTooltip(this.intervalValue);
}
Expand Down
129 changes: 129 additions & 0 deletions src/app/applications/services/applications-grpc.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { ApplicationRawEnumField, ApplicationsClient, FilterStringOperator, ListApplicationsRequest } from '@aneoconsultingfr/armonik.api.angular';
import { TestBed } from '@angular/core/testing';
import { FilterDefinitionRootString } from '@app/types/filter-definition';
import { UtilsService } from '@services/utils.service';
import { ApplicationsFiltersService } from './applications-filters.service';
import { ApplicationsGrpcService } from './applications-grpc.service';
import { ApplicationRawFilter, ApplicationRawListOptions } from '../types';

describe('ApplicationsGrpcService', () => {
let service: ApplicationsGrpcService;

const mockApplicationFiltersService = {
retrieveFiltersDefinitions: jest.fn().mockImplementation(() => {
const definitions: FilterDefinitionRootString<ApplicationRawEnumField>[] = [
{
for: 'root',
field: 1,
type: 'string'
},
{
for: 'root',
field: 2,
type: 'number'
} as unknown as FilterDefinitionRootString<ApplicationRawEnumField>
];
return definitions;
})
};

const mockApplicationsClient = {
listApplications: jest.fn().mockImplementation((data) => data)
};

const options: ApplicationRawListOptions = {
pageIndex: 0,
pageSize: 10,
sort: {
active: 'name',
direction: 'asc'
}
};

const correctfilters: ApplicationRawFilter = [[
{
field: 1,
for: 'root',
operator: 0,
value: 'someValue'
}
]];

const uncorrectfilters: ApplicationRawFilter = [[
{
field: 2,
for: 'root',
operator: 0,
value: 123
}
]];

beforeEach(() => {
service = TestBed.configureTestingModule({
providers: [
ApplicationsGrpcService,
UtilsService<ApplicationRawEnumField>,
{ provide: ApplicationsClient, useValue: mockApplicationsClient },
{ provide: ApplicationsFiltersService, useValue: mockApplicationFiltersService }
]
}).inject(ApplicationsGrpcService);
});

it('should create', () => {
expect(service).toBeTruthy();
});

it('should not get', () => {
expect(() => {service.get$();}).toThrowError('This method must never be called');
});

it('should create a request without filters', () => {
const listResult = new ListApplicationsRequest({
page: 0,
pageSize: 10,
sort: {
direction: 1,
fields: [{
applicationField: {
field: 1
}
}]
},
filters: {or: []}
});
expect(service.list$(options, [])).toEqual(listResult);
});

it('should create a request with filters', () => {
const listResult = new ListApplicationsRequest({
page: 0,
pageSize: 10,
sort: {
direction: 1,
fields: [{
applicationField: {
field: 1
}
}]
},
filters: { or: [{
and: [{
field: {
applicationField: {
field: 1
}
},
filterString: {
value: 'someValue',
operator: 0 as FilterStringOperator
}
}]
}]}
});
expect(service.list$(options, correctfilters)).toEqual(listResult);
});

it('should throw error in case on unexpected type', () => {
expect(() => {service.list$(options, uncorrectfilters);}).toThrowError('Type number not supported');
});
});
149 changes: 149 additions & 0 deletions src/app/applications/services/applications-index.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { TestBed } from '@angular/core/testing';
import { DefaultConfigService } from '@services/default-config.service';
import { TableService } from '@services/table.service';
import { ApplicationsIndexService } from './applications-index.service';
import { ApplicationRawColumnKey, ApplicationRawListOptions } from '../types';


describe('TasksIndexService', () => {
let service: ApplicationsIndexService;

const expectedColumnLabels: Record<ApplicationRawColumnKey, string> = {
name: $localize`Name`,
namespace: $localize`Namespace`,
service: $localize`Service`,
version: $localize`Version`,
count: $localize`Tasks by Status`,
actions: $localize`Actions`,
};

const expectDefaultOptions :ApplicationRawListOptions = {
pageIndex: 0,
pageSize: 10,
sort: {
active: 'name',
direction: 'asc'
},
};
const expectedDefaultColumns = new DefaultConfigService().defaultApplications.columns;

const expectedDefaultIntervalValue = new DefaultConfigService().defaultApplications.interval;
const mockTableService = {
saveIntervalValue: jest.fn(),
restoreIntervalValue: jest.fn(),
saveOptions: jest.fn(),
restoreOptions: jest.fn(),
saveColumns: jest.fn(),
restoreColumns: jest.fn(),
resetColumns: jest.fn(),
saveViewInLogs: jest.fn(),
restoreViewInLogs: jest.fn()
};


beforeEach(() => {
service = TestBed.configureTestingModule({
providers: [
ApplicationsIndexService,
DefaultConfigService,
{provide: TableService, useValue: mockTableService}
]
}).inject(ApplicationsIndexService);
});

test('Create ApplicationsIndexService', ()=> {
expect(service).toBeTruthy();
});


describe('Columns', ()=> {
test('the service should label the right column among available columns labels',() => {
for(const [key] of Object.entries(expectedColumnLabels)) {
expect(service.columnToLabel(key as ApplicationRawColumnKey)).toEqual(service.columnsLabels[`${key}` as ApplicationRawColumnKey]);
}
});
});

describe('Table', () => {
it('should return true if the column is actions', () =>{
expect(service.isActionsColumn('actions')).toEqual(true);
});
it('should return false if the column is not actions', () =>{
expect(service.isActionsColumn('name')).toEqual(false);
});

it('should return true if the column is id', () =>{
expect(service.isCountColumn('count')).toEqual(true);
});
it('should return false if the column is not id', () =>{
expect(service.isCountColumn('name')).toEqual(false);
});

it('should return true if the column is a simple column', () =>{
expect(service.isSimpleColumn('name')).toEqual(true);
});
it('should return false if the column is not a simple column', () =>{
expect(service.isSimpleColumn('actions')).toEqual(false);
});

it('should return true if the column is not sortable', () =>{
expect(service.isNotSortableColumn('count')).toEqual(true);
});
it('should return false if the column is sortable', () =>{
expect(service.isNotSortableColumn('name')).toEqual(false);
});
});

describe('Interval', ()=>{
it('should call saveIntervalValue from TableService', ()=>{
service.saveIntervalValue(9);
expect(mockTableService.saveIntervalValue).toBeCalledWith('applications-interval', 9);
});

it('should call restoreIntervalValue from TableService', ()=>{
service.restoreIntervalValue();
expect(mockTableService.restoreIntervalValue).toHaveBeenCalledWith('applications-interval');
});

it('should return defaultIntervalValue when restoreIntervalValue from TableService returns null', () => {
mockTableService.restoreIntervalValue.mockImplementationOnce(() => null);
expect(service.restoreIntervalValue()).toEqual(expectedDefaultIntervalValue);
});

});

describe('Options', ()=>{
it('should call saveOptions from TableService', ()=>{
service.saveOptions(expectDefaultOptions);
expect(mockTableService.saveOptions).toBeCalledWith('applications-options',expectDefaultOptions);
});

it('should call restoreOptions from TableService', ()=>{
service.restoreOptions();
expect(mockTableService.restoreOptions).toBeCalledWith('applications-options',expectDefaultOptions);
});
});

describe('Columns', ()=>{
it('should call saveColumns from TableService', ()=>{
service.saveColumns(['namespace', 'actions', 'version']);
expect(mockTableService.saveColumns).toBeCalledWith('applications-columns', ['namespace', 'actions', 'version']);
});

it('should call restoreColumns from TableService', ()=>{
service.restoreColumns();
expect(mockTableService.restoreColumns).toBeCalledWith('applications-columns');
});

it('should return defaultColums when restoreColumns from TableService returns null', ()=>{
mockTableService.restoreColumns.mockImplementationOnce(() => null);
expect(service.restoreColumns()).toEqual(expectedDefaultColumns);
});

it('should call resetColumns from TableService', ()=>{
service.resetColumns();
expect(mockTableService.resetColumns).toBeCalledWith('applications-columns');
expect(service.resetColumns()).toEqual(expectedDefaultColumns);
});
});
});
13 changes: 13 additions & 0 deletions src/app/applications/services/applications-index.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class ApplicationsIndexService {
readonly defaultOptions: ApplicationRawListOptions = this.#defaultConfigService.defaultApplications.options;

readonly defaultIntervalValue = this.#defaultConfigService.defaultApplications.interval;
readonly defaultLockColumnValue = this.#defaultConfigService.defaultApplications.lockColumns;

#tableService = inject(TableService);

Expand Down Expand Up @@ -62,6 +63,18 @@ export class ApplicationsIndexService {
return this.#tableService.restoreIntervalValue('applications-interval') ?? this.defaultIntervalValue;
}

/**
* Lock columns
*/

saveLockColumns(value: boolean): void {
this.#tableService.saveLockColumns('applications-lock-columns', value);
}

restoreLockColumns(): boolean {
return this.#tableService.restoreLockColumns('applications-lock-columns') ?? this.defaultLockColumnValue;
}

/**
* Options
*/
Expand Down
3 changes: 2 additions & 1 deletion src/app/components/columns-button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ColumnsModifyDialogComponent } from './columns-modify-dialog.component'
@Component({
selector: 'app-columns-button',
template: `
<button mat-stroked-button (click)="openModifyColumnsDialog()">
<button [disabled]="disabled" mat-stroked-button (click)="openModifyColumnsDialog()">
<mat-icon aria-hidden="true" [fontIcon]="getIcon('modify-columns')"></mat-icon>
<span i18n="Open a dialog on click">Modify Columns</span>
</button>
Expand All @@ -31,6 +31,7 @@ export class ColumnsButtonComponent<T extends object, O extends object> {
@Input({ required: true }) columnsLabels: Record<ColumnKey<T, O>, string>;
@Input({ required: true }) displayedColumns: ColumnKey<T, O>[] = [];
@Input({ required: true }) availableColumns: ColumnKey<T, O>[];
@Input({ required: true}) disabled: boolean = false;

@Output() displayedColumnsChange: EventEmitter<ColumnKey<T, O>[]> = new EventEmitter<ColumnKey<T, O>[]>();

Expand Down
Loading