Skip to content

Commit

Permalink
NAS-125376 / 24.04 / Fix changes and emit in AdvancedSearchComponent (#…
Browse files Browse the repository at this point in the history
…9289)

* NAS-125468: More improvements on audit page

* NAS-125468: More improvements on audit page

* NAS-125468: More improvements on audit page

* NAS-125568: Audit Query Value Transformation for Enums

* NAS-125376: NAS_125376: Fix changes and emit in AdvancedSearchComponent

* NAS-125376: NAS_125376: Fix changes and emit in AdvancedSearchComponent

* NAS-125376: NAS_125376: Fix changes and emit in AdvancedSearchComponent

* NAS-125376: PR update

* NAS-125376: PR update

* NAS-125376: PR update
  • Loading branch information
AlexKarpov98 authored Dec 7, 2023
1 parent 9ed6dd6 commit 97de07e
Show file tree
Hide file tree
Showing 18 changed files with 383 additions and 69 deletions.
10 changes: 10 additions & 0 deletions src/app/enums/audit-event.enum.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { marker as T } from '@biesbjerg/ngx-translate-extract-marker';

export enum AuditService {
Smb = 'SMB',
Middleware = 'MIDDLEWARE',
}

export enum AuditEvent {
Connect = 'CONNECT',
Disconnect = 'DISCONNECT',
Expand All @@ -18,6 +23,11 @@ export enum AuditEvent {
MethodCall = 'METHOD_CALL',
}

export const auditServiceLabels = new Map<AuditService, string>([
[AuditService.Smb, T('SMB')],
[AuditService.Middleware, T('Middleware')],
]);

export const auditEventLabels = new Map<AuditEvent, string>([
[AuditEvent.Connect, T('Connect')],
[AuditEvent.Disconnect, T('Disconnect')],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
</a>

<span
*ngIf="isEditorEmpty"
class="reset-icon reset-input"
[class.hidden]="!editorHasValue"
(click)="onResetInput()"
>
<ix-icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
}
}

.hidden {
display: none !important;
}

.reset-icon {
margin-top: 2px;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { auditEventLabels, AuditService } from 'app/enums/audit-event.enum';
import { QueryFilters } from 'app/interfaces/query-api.interface';
import { User } from 'app/interfaces/user.interface';
import { AdvancedSearchComponent } from 'app/modules/search-input/components/advanced-search/advanced-search.component';
import { AdvancedSearchHarness } from 'app/modules/search-input/components/advanced-search/advanced-search.harness';
import { AdvancedSearchAutocompleteService } from 'app/modules/search-input/services/advanced-search-autocomplete.service';
import { QueryParserService } from 'app/modules/search-input/services/query-parser/query-parser.service';
import { QueryToApiService } from 'app/modules/search-input/services/query-to-api/query-to-api.service';
import { PropertyType, SearchProperty } from 'app/modules/search-input/types/search-property.interface';

describe('AdvancedSearchComponent', () => {
let spectator: Spectator<AdvancedSearchComponent<User>>;
Expand All @@ -19,26 +22,104 @@ describe('AdvancedSearchComponent', () => {
],
});

beforeEach(async () => {
spectator = createComponent();
jest.spyOn(spectator.component.switchToBasic, 'emit');
searchHarness = await TestbedHarnessEnvironment.harnessForFixture(spectator.fixture, AdvancedSearchHarness);
});
describe('no default input provided', () => {
beforeEach(async () => {
spectator = createComponent();
jest.spyOn(spectator.component.switchToBasic, 'emit');
searchHarness = await TestbedHarnessEnvironment.harnessForFixture(spectator.fixture, AdvancedSearchHarness);
});

it('resets text area when reset icon is pressed', async () => {
await searchHarness.setValue('test');
await (await searchHarness.getResetIcon()).click();
const placeholderText = await searchHarness.getPlaceholder();

// TODO: Test case for emit
expect(await searchHarness.getValue()).toBe(placeholderText);
});

// TODO: Fix test
it.skip('resets text area when reset icon is pressed', async () => {
await searchHarness.setValue('test');
await (await searchHarness.getResetIcon()).click();
it('emits (switchToBasic) when Switch To Basic is pressed', async () => {
expect(await (await searchHarness.getSwitchLink()).text()).toBe('Switch To Basic');
await searchHarness.clickSwitchToBasic();

expect(await searchHarness.getValue()).toBe('');
expect(spectator.component.switchToBasic.emit).toHaveBeenCalled();
});
});

it('emits (switchToBasic) when Switch To Basic is pressed', async () => {
expect(await (await searchHarness.getSwitchLink()).text()).toBe('Switch To Basic');
await searchHarness.clickSwitchToBasic();
describe('has default input provided', () => {
beforeEach(async () => {
spectator = createComponent({
props: {
query: [
[
'OR',
[
[
[
'event',
'in',
[
'AUTHENTICATION',
'CLOSE',
],
],
[
'username',
'=',
'admin',
],
[
'service',
'=',
'MIDDLEWARE',
],
],
[
[
'event',
'=',
'AUTHENTICATION',
],
[
'service',
'=',
'SMB',
],
],
],
],
] as QueryFilters<User>,
properties: [
{
label: 'Username',
property: 'username',
propertyType: PropertyType.Text,
},
{
label: 'Сервіс',
property: 'service',
propertyType: PropertyType.Text,
enumMap: new Map<AuditService, string>([
[AuditService.Middleware, 'Проміжне програмне забезпечення'],
[AuditService.Smb, 'Ес-ем-бе'],
]),
},
{
label: 'Event',
property: 'event',
enumMap: auditEventLabels,
propertyType: PropertyType.Text,
},
] as SearchProperty<User>[],
},
});
jest.spyOn(spectator.component.switchToBasic, 'emit');
searchHarness = await TestbedHarnessEnvironment.harnessForFixture(spectator.fixture, AdvancedSearchHarness);
});

expect(spectator.component.switchToBasic.emit).toHaveBeenCalled();
it('correctly sets predefined input value', async () => {
expect(await searchHarness.getValue()).toBe(
'(("Event" IN ("Authentication", "Close") AND "Username" = "admin" AND "Сервіс" = "Проміжне програмне забезпечення") OR ("Event" = "Authentication" AND "Сервіс" = "Ес-ем-бе"))',
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ElementRef,
EventEmitter,
Input,
OnChanges, OnInit,
OnInit,
Output,
ViewChild,
} from '@angular/core';
Expand All @@ -14,7 +14,6 @@ import { EditorState } from '@codemirror/state';
import { EditorView, placeholder } from '@codemirror/view';
import { format } from 'date-fns';
import { QueryFilters } from 'app/interfaces/query-api.interface';
import { IxSimpleChanges } from 'app/interfaces/simple-changes.interface';
import { AdvancedSearchAutocompleteService } from 'app/modules/search-input/services/advanced-search-autocomplete.service';
import { QueryParserService } from 'app/modules/search-input/services/query-parser/query-parser.service';
import { QueryToApiService } from 'app/modules/search-input/services/query-to-api/query-to-api.service';
Expand All @@ -26,7 +25,7 @@ import { SearchProperty } from 'app/modules/search-input/types/search-property.i
styleUrls: ['./advanced-search.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AdvancedSearchComponent<T> implements OnInit, OnChanges {
export class AdvancedSearchComponent<T> implements OnInit {
@Input() query: QueryFilters<T> = [];
@Input() properties: SearchProperty<T>[] = [];

Expand All @@ -39,7 +38,7 @@ export class AdvancedSearchComponent<T> implements OnInit, OnChanges {
queryInputValue: string;
private editorView: EditorView;

get isEditorEmpty(): boolean {
get editorHasValue(): boolean {
return (this.editorView.state.doc as unknown as { text: string[] })?.text?.[0] !== '';
}
showDatePicker$ = this.advancedSearchAutocomplete.showDatePicker$;
Expand All @@ -51,17 +50,19 @@ export class AdvancedSearchComponent<T> implements OnInit, OnChanges {
private cdr: ChangeDetectorRef,
) {}

ngOnChanges(changes: IxSimpleChanges<this>): void {
if (changes.query && this.editorView) {
// TODO:
// this.setEditorContents(this.queryParser.formatFiltersToQuery(this.query, this.properties));
}
}

ngOnInit(): void {
this.initEditor();
this.advancedSearchAutocomplete.setProperties(this.properties);
this.advancedSearchAutocomplete.setEditorView(this.editorView);

if (this.query) {
this.setEditorContents(
this.queryParser.formatFiltersToQuery(
this.query as QueryFilters<never>,
this.properties as SearchProperty<never>[],
),
);
}
}

startSuggestionsCompletion(): void {
Expand Down Expand Up @@ -115,8 +116,12 @@ export class AdvancedSearchComponent<T> implements OnInit, OnChanges {
this.hasQueryErrors = Boolean(this.queryInputValue.length && parsedQuery.hasErrors);
this.cdr.markForCheck();

if (this.queryInputValue === '') {
this.onResetInput();
}

if (parsedQuery.hasErrors) {
// TODO: Handle errors.
// TODO: Handle errors. --> https://ixsystems.atlassian.net/browse/NAS-125375
return;
}

Expand All @@ -130,11 +135,7 @@ export class AdvancedSearchComponent<T> implements OnInit, OnChanges {

private setEditorContents(contents: string, from = 0, to?: number): void {
this.editorView.dispatch({
changes: {
from,
to,
insert: contents,
},
changes: { from, to, insert: contents },
selection: { anchor: from + contents.length },
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ export class AdvancedSearchHarness extends ComponentHarness {
static hostSelector = 'ix-advanced-search';

getResetIcon = this.locatorFor('.reset-icon');
getInputArea = this.locatorFor('.input-area');
getInputArea = this.locatorFor('.cm-content');
getInputPlaceholder = this.locatorFor('.cm-placeholder');
getSwitchLink = this.locatorFor('.switch-link');

async getValue(): Promise<string> {
return (await this.getInputArea()).text();
return (await (this.getInputArea())).text();
}

async getPlaceholder(): Promise<string> {
return (await (this.getInputPlaceholder())).text();
}

async setValue(value: string): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { PropertyType, SearchProperty } from 'app/modules/search-input/types/sea
const inComparator = 'IN';
const ninComparator = 'NIN';
const comparatorSuggestions = [
'=', '!=', '<', '>', '<=', '>=', inComparator, ninComparator, '~', '^', '!^', '$', '!$',
'=', '!=', '<', '>', '<=', '>=', inComparator, ninComparator, 'RIN', 'RNIN', '~', '^', '!^', '$', '!$',
] as QueryComparator[];

const orSuggestion = 'OR';
Expand Down Expand Up @@ -110,12 +110,10 @@ export class AdvancedSearchAutocompleteService<T> {
to = to + 1;
anchor = from + updatedValue.length - 1;
}
} else if (regexMap.containsWhitespace.test(updatedValue)) {
updatedValue = `"${updatedValue}"`;
anchor = anchor + 2;
}

if (/\s/.test(updatedValue) && !/^["']|["']$/.test(updatedValue)) {
} else if (
regexMap.containsWhitespace.test(updatedValue) && !regexMap.looselyQuotedString.test(updatedValue)
&& !updatedValue.startsWith('(') && !updatedValue.endsWith(')')
) {
updatedValue = `"${updatedValue}"`;
anchor = anchor + 2;
}
Expand Down
Loading

0 comments on commit 97de07e

Please sign in to comment.