[ACS-8398] unit tests part 3 (#4163)

* ACS-8398 Unit tests for search ai effects

* ACS-8398 Unit tests for canDisplayKnowledgeRetrievalButton rule

* ACS-8398 Unit tests for changes in document base page

* ACS-8398 Added unit tests for changes in recent files component

* ACS-8398 Unit tests for changes in lists pages

* ACS-8398 Moved variable to inside of describe

* ACS-8398 Moved repeated code to function

* ACS-8398 Reverted one change

* ACS-8398 Fix after rebase

* ACS-8398 Fix issue with repeated code

* ACS-8398 Fix issue with repeated code

* ACS-8398 Fixed unit tests

* ACS-8398 Fixed unit tests

* ACS-8398 Trigger job
This commit is contained in:
AleksanderSklorz 2024-10-07 13:50:01 +02:00 committed by GitHub
parent 3ec6d0be32
commit 0fb9f9ebe3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 325 additions and 39 deletions

View File

@ -31,6 +31,7 @@ import { AppTestingModule } from '../../testing/app-testing.module';
import { AppService, ContentApiService } from '@alfresco/aca-shared';
import { getTitleElementText } from '../../testing/test-utils';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { testHeader } from '../../testing/document-base-page-utils';
describe('FavoritesComponent', () => {
let fixture: ComponentFixture<FavoritesComponent>;
@ -140,4 +141,6 @@ describe('FavoritesComponent', () => {
fixture.detectChanges();
expect(getTitleElementText(fixture)).toBe('APP.HEADER.SELECTED');
});
testHeader(FavoritesComponent);
});

View File

@ -35,6 +35,7 @@ import { By } from '@angular/platform-browser';
import { NodeEntry, NodePaging, Node, PathElement } from '@alfresco/js-api';
import { DocumentListPresetRef } from '@alfresco/adf-extensions';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { testHeader } from '../../testing/document-base-page-utils';
describe('FilesComponent', () => {
let node;
@ -473,4 +474,6 @@ describe('FilesComponent', () => {
expect(resetNewFolderPaginationSpy).not.toHaveBeenCalled();
});
});
testHeader(FilesComponent);
});

View File

@ -31,6 +31,7 @@ import { NodePaging, SearchApi } from '@alfresco/js-api';
import { of } from 'rxjs';
import { getTitleElementText } from '../../testing/test-utils';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { testHeader } from '../../testing/document-base-page-utils';
describe('RecentFilesComponent', () => {
let fixture: ComponentFixture<RecentFilesComponent>;
@ -110,4 +111,6 @@ describe('RecentFilesComponent', () => {
fixture.detectChanges();
expect(getTitleElementText(fixture)).toBe('APP.HEADER.SELECTED');
});
testHeader(RecentFilesComponent);
});

View File

@ -34,6 +34,7 @@ import { BehaviorSubject, Subject } from 'rxjs';
import { AppTestingModule } from '../../../testing/app-testing.module';
import { AppService } from '@alfresco/aca-shared';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { testHeader } from '../../../testing/document-base-page-utils';
describe('SearchComponent', () => {
let component: SearchResultsComponent;
@ -279,4 +280,6 @@ describe('SearchComponent', () => {
expect(queryBuilder.userQuery).toBe(`((=cm:tag:"orange"))`);
expect(queryBuilder.update).toHaveBeenCalled();
});
testHeader(SearchResultsComponent, false);
});

View File

@ -31,8 +31,9 @@ import { By } from '@angular/platform-browser';
import { SharedLinkPaging } from '@alfresco/js-api';
import { AppService } from '@alfresco/aca-shared';
import { getTitleElementText } from '../../testing/test-utils';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { testHeader } from '../../testing/document-base-page-utils';
describe('SharedFilesComponent', () => {
let fixture: ComponentFixture<SharedFilesComponent>;
@ -40,7 +41,8 @@ describe('SharedFilesComponent', () => {
let component: SharedFilesComponent;
const routerMock = {
routerState: { root: '' },
url: 'shared-files'
url: 'shared-files',
events: new Subject<NavigationStart>()
};
const route = {
snapshot: {
@ -104,4 +106,6 @@ describe('SharedFilesComponent', () => {
const pagination = fixture.debugElement.query(By.css('.adf-pagination'));
expect(pagination).toBeNull();
});
testHeader(SharedFilesComponent);
});

View File

@ -0,0 +1,77 @@
/*!
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { TestBed } from '@angular/core/testing';
import { EffectsModule } from '@ngrx/effects';
import { SearchAiEffects } from './search-ai.effects';
import { Store } from '@ngrx/store';
import { AppTestingModule } from '../../testing/app-testing.module';
import { SearchAiNavigationService } from '../../services/search-ai-navigation.service';
import { AppStore, SearchByTermAiAction, ToggleAISearchInput } from '@alfresco/aca-shared/store';
import { SearchAiService } from '@alfresco/adf-content-services';
describe('SearchAiEffects', () => {
let store: Store<AppStore>;
const agentId = '1';
const searchTerm = 'test';
beforeEach(() => {
TestBed.configureTestingModule({
imports: [AppTestingModule, EffectsModule.forRoot([SearchAiEffects])]
});
store = TestBed.inject(Store);
});
describe('searchByTerm$', () => {
it('should call navigateToSearchAi on SearchAiNavigationService', () => {
const searchAiNavigationService = TestBed.inject(SearchAiNavigationService);
spyOn(searchAiNavigationService, 'navigateToSearchAi');
store.dispatch(
new SearchByTermAiAction({
searchTerm,
agentId
})
);
expect(searchAiNavigationService.navigateToSearchAi).toHaveBeenCalledWith({
query: searchTerm,
agentId
});
});
});
describe('toggleAISearchInput$', () => {
it('should call updateSearchAiInputState on SearchAiService', () => {
const searchAiService = TestBed.inject(SearchAiService);
spyOn(searchAiService, 'updateSearchAiInputState');
store.dispatch(new ToggleAISearchInput(agentId, searchTerm));
expect(searchAiService.updateSearchAiInputState).toHaveBeenCalledWith({
active: true,
selectedAgentId: agentId,
searchTerm
});
});
});
});

View File

@ -0,0 +1,103 @@
/*!
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { BehaviorSubject, Subject } from 'rxjs';
import { AgentService, SearchAiInputState, SearchAiService } from '@alfresco/adf-content-services';
import { DebugElement, Type } from '@angular/core';
import { By } from '@angular/platform-browser';
import { SearchAiInputContainerComponent } from '../components/knowledge-retrieval/search-ai/search-ai-input-container/search-ai-input-container.component';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageComponent } from '@alfresco/aca-shared';
import { Agent } from '@alfresco/js-api/typings';
export const testHeader = <T extends PageComponent>(component: Type<T>, checkHeaderVisibility = true) => {
describe('Header', () => {
let fixture: ComponentFixture<T>;
let toggleSearchAiInput$: BehaviorSubject<SearchAiInputState>;
const getSearchAiInputElement = (): DebugElement => fixture.debugElement.query(By.directive(SearchAiInputContainerComponent));
const getHeaderElement = (): DebugElement => fixture.debugElement.query(By.css('.aca-header-container'));
beforeEach(() => {
fixture = TestBed.createComponent(component);
toggleSearchAiInput$ = new BehaviorSubject<SearchAiInputState>({
searchTerm: ''
} as SearchAiInputState);
TestBed.inject(SearchAiService).toggleSearchAiInput$ = toggleSearchAiInput$;
spyOn(TestBed.inject(AgentService), 'getAgents').and.returnValue(new Subject<Agent[]>());
fixture.detectChanges();
});
it('should display ai input if input is active', () => {
toggleSearchAiInput$.next({
active: true,
searchTerm: ''
});
fixture.detectChanges();
expect(getSearchAiInputElement()).not.toBeNull();
});
it('should not display ai input if input is not active', () => {
toggleSearchAiInput$.next({
active: false,
searchTerm: ''
});
fixture.detectChanges();
expect(getSearchAiInputElement()).toBeNull();
});
it('should not display ai input by default', () => {
expect(getSearchAiInputElement()).toBeNull();
});
if (checkHeaderVisibility) {
it('should not display header if input is active', () => {
toggleSearchAiInput$.next({
active: true,
searchTerm: ''
});
fixture.detectChanges();
expect(getHeaderElement()).toBeNull();
});
it('should display header if input is not active', () => {
toggleSearchAiInput$.next({
active: false,
searchTerm: ''
});
fixture.detectChanges();
expect(getHeaderElement()).not.toBeNull();
});
it('should display header by default', () => {
expect(getHeaderElement()).not.toBeNull();
});
}
});
};

View File

@ -26,6 +26,7 @@ import * as app from './app.rules';
import { TestRuleContext } from './test-rule-context';
import { NodeEntry, RepositoryInfo, StatusInfo } from '@alfresco/js-api';
import { getFileExtension } from './app.rules';
import { AppConfigService } from '@alfresco/adf-core';
describe('app.evaluators', () => {
let context: TestRuleContext;
@ -540,44 +541,117 @@ describe('app.evaluators', () => {
});
});
describe('isKnowledgeRetrievalEnabled', () => {
it('should call context.appConfig.get with correct parameters', () => {
context.appConfig = { get: jasmine.createSpy() } as any;
describe('canDisplayKnowledgeRetrievalButton', () => {
const testCanDisplayKnowledgeRetrievalButton = (testTitle: string, url: string, knowledgeRetrievalEnabled: boolean, expected: boolean) => {
it(testTitle, () => {
context.appConfig = jasmine.createSpyObj<AppConfigService>({
get: knowledgeRetrievalEnabled
});
context.navigation.url = url;
expect(app.canDisplayKnowledgeRetrievalButton(context)).toBe(expected);
});
};
[
{
pageName: 'personal files',
pageUrl: '/personal-files'
},
{
pageName: 'shared files',
pageUrl: '/shared'
},
{
pageName: 'recent files',
pageUrl: '/recent-files'
},
{
pageName: 'favorites',
pageUrl: '/favorites'
},
{
pageName: 'library content',
pageUrl: '/libraries/some-id'
}
].forEach((testCase) => {
testCanDisplayKnowledgeRetrievalButton(
`should return false if get from appConfig returns false and navigation is ${testCase.pageName}`,
testCase.pageUrl,
false,
false
);
testCanDisplayKnowledgeRetrievalButton(
`should return true if get from appConfig returns true and navigation is ${testCase.pageName}`,
testCase.pageUrl,
true,
true
);
});
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns false and navigation is search results but not for libraries',
'/search',
false,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return true if get from appConfig returns true and navigation is search results but not for libraries',
'/search',
true,
true
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns false and navigation is search results for libraries',
'/search/libraries',
false,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns true and navigation is search results for libraries',
'/search/libraries',
true,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns false and navigation is libraries',
'/libraries',
false,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns true and navigation is libraries',
'/libraries',
true,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns false and navigation is incorrect',
'/my-special-files',
false,
false
);
testCanDisplayKnowledgeRetrievalButton(
'should return false if get from appConfig returns true but navigation is incorrect',
'/my-special-files',
true,
false
);
it('should call get on context.appConfig with correct parameters', () => {
context.appConfig = jasmine.createSpyObj<AppConfigService>({
get: false
});
app.canDisplayKnowledgeRetrievalButton(context);
expect(context.appConfig.get).toHaveBeenCalledWith('plugins.knowledgeRetrievalEnabled', true);
});
it('should return false if get from appConfig returns false', () => {
expect(
app.canDisplayKnowledgeRetrievalButton({
appConfig: {
get: () => false
}
} as any)
).toBeFalse();
});
it('should return true if get from appConfig returns true and navigation is correct', () => {
expect(
app.canDisplayKnowledgeRetrievalButton({
navigation: { url: '/personal-files' },
appConfig: {
get: () => true
}
} as any)
).toBeTrue();
});
it('should return false if get from appConfig returns true, but navigation is not correct', () => {
expect(
app.canDisplayKnowledgeRetrievalButton({
navigation: { url: '/my-special-files' },
appConfig: {
get: () => true
}
} as any)
).toBeFalse();
expect(context.appConfig.get).toHaveBeenCalledWith('plugins.knowledgeRetrievalEnabled', false);
});
});

View File

@ -30,7 +30,7 @@ import { NodeEntry, NodePaging } from '@alfresco/js-api';
import { DocumentBasePageService } from './document-base-page.service';
import { Store } from '@ngrx/store';
import { Component } from '@angular/core';
import { DiscoveryApiService, DocumentListComponent, DocumentListService, SearchAiService } from '@alfresco/adf-content-services';
import { DiscoveryApiService, DocumentListComponent, DocumentListService, SearchAiInputState, SearchAiService } from '@alfresco/adf-content-services';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { AuthModule, UserPreferencesService } from '@alfresco/adf-core';
import { of, Subscription } from 'rxjs';
@ -278,6 +278,22 @@ describe('PageComponent', () => {
expect(searchAiService.updateSearchAiInputState).not.toHaveBeenCalled();
});
});
describe('SearchAiService toggleSearchAiInput$ event handler', () => {
it('should set searchAiInputState', () => {
const initialSearchAiInputState = component.searchAiInputState;
const searchAiInputState: SearchAiInputState = {
active: true
};
searchAiService.toggleSearchAiInput$ = of(searchAiInputState);
component.ngOnInit();
expect(component.searchAiInputState).toBe(searchAiInputState);
expect(initialSearchAiInputState).toEqual({
active: false
});
});
});
});
describe('Info Drawer state', () => {