Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module.exports = {
}
],
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/prefer-optional-chain': 'warn',
'@typescript-eslint/prefer-readonly': 'error',
'@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/no-require-imports': 'off',
Expand All @@ -105,7 +105,6 @@ module.exports = {
'prefer-arrow/prefer-arrow-functions': 'off',
'prefer-promise-reject-errors': 'error',
'brace-style': 'off',
'@typescript-eslint/brace-style': 'error',
'comma-dangle': 'error',
'default-case': 'error',
'import/order': 'off',
Expand Down
Empty file added .npmrc
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe('SearchChipListComponent', () => {
});

it('should remove the entry upon remove button click', async () => {
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.callThrough();
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.stub();

searchFacetFiltersService.selectedBuckets = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ export const LogicalSearchFields = {
export type LogicalSearchFields = (typeof LogicalSearchFields)[keyof typeof LogicalSearchFields];

export type LogicalSearchConditionEnumValuedKeys = { [T in LogicalSearchFields]: string };
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface LogicalSearchCondition extends LogicalSearchConditionEnumValuedKeys {}
export type LogicalSearchCondition = LogicalSearchConditionEnumValuedKeys;

@Component({
selector: 'adf-search-logical-filter',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export class SearchFacetFiltersService {
unselectFacetBucket(facetField: FacetField, bucket: FacetFieldBucket) {
if (bucket) {
bucket.checked = false;
this.queryBuilder.removeUserFacetBucket(facetField.field, bucket);
this.queryBuilder.removeUserFacetBucket(facetField?.field, bucket);
this.updateSelectedBuckets();
this.queryBuilder.update();
}
Expand Down
1 change: 1 addition & 0 deletions lib/content-services/src/lib/security/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
*/

export * from './services/security-controls-groups-marks-security.service';
export * from './services/models/security-controls-mark-response.interface';
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
[mimeType]="mimeType"
[nodeMimeType]="nodeMimeType"
[urlFile]="urlFileContent"
[blobFile]="blobFileContent"
[tracks]="tracks"
[readOnly]="readOnly || !canEditNode"
[showToolbarDividers]="showToolbarDividers"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,20 @@ describe('AlfrescoViewerComponent', () => {
expect(component.nodesApi.getNode).toHaveBeenCalledTimes(2);
}));

it('should append version of the file to the file content URL', fakeAsync(() => {
it('should append version of the file to the file content URL', async () => {
const mockBlob = new Blob(['fake pdf content'], { type: 'application/pdf' });
const mockResponse = {
ok: true,
blob: () => Promise.resolve(mockBlob)
} as Response;
spyOn(window, 'fetch').and.returnValue(Promise.resolve(mockResponse));

spyOn(component.nodesApi, 'getNode').and.returnValue(
Promise.resolve(
new NodeEntry({
entry: new Node({
name: 'file1.pdf',
content: new ContentInfo(),
content: new ContentInfo({ mimeType: 'application/pdf' }),
properties: { 'cm:versionLabel': '10' }
})
})
Expand All @@ -392,11 +399,12 @@ describe('AlfrescoViewerComponent', () => {
component.showViewer = true;
component.versionId = null;
component.ngOnChanges(getSimpleChanges('id1'));
tick();

await fixture.whenStable();

expect(component.fileName).toBe('file1.pdf');
expect(component.urlFileContent).toContain('/public/alfresco/versions/1/nodes/id1/content?attachment=false&10');
}));
expect(component.blobFileContent).toBe(mockBlob);
});

it('should change display name every time node`s version changes', fakeAsync(() => {
spyOn(component.nodesApi, 'getNode').and.returnValue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@

versionEntry: VersionEntry;
urlFileContent: string;
blobFileContent: Blob;
fileName: string;
mimeType: string;
nodeMimeType: string;
Expand Down Expand Up @@ -275,6 +276,7 @@
private async onNodeUpdated(node: Node) {
if (node && node.id === this.nodeId) {
this.generateCacheBusterNumber();
this.blobFileContent = null;

await this.setUpNodeFile(node);
}
Expand All @@ -299,6 +301,7 @@

private async setupNode() {
try {
this.blobFileContent = null;
this.nodeEntry = await this.nodesApi.getNode(this.nodeId, { include: ['allowableOperations'] });
if (this.versionId) {
this.versionEntry = await this.versionsApi.getVersion(this.nodeId, this.versionId);
Expand All @@ -312,7 +315,7 @@
}
}

private async setUpNodeFile(nodeData: Node, versionData?: Version): Promise<void> {

Check failure on line 318 in lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 23 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=Alfresco_alfresco-ng2-components&issues=AZ1DruIpnyOtrsjoaG5l&open=AZ1DruIpnyOtrsjoaG5l&pullRequest=11657
this.canEditNode = this.contentService.hasAllowableOperations(nodeData, 'update');
let mimeType: string;
let nodeMimeType: string;
Expand Down Expand Up @@ -351,12 +354,34 @@
}
} else if (viewerType === 'media') {
this.tracks = await this.renditionService.generateMediaTracksRendition(this.nodeId);
} else if (viewerType === 'pdf') {
try {
const contentUrl = versionData
? this.contentApi.getVersionContentUrl(this.nodeId, versionData.id)
: this.contentApi.getContentUrl(this.nodeId);

// Fetch the content as Blob using fetch API with credentials
const response = await fetch(contentUrl, {
credentials: 'include',
headers: {
'Cache-Control': 'no-cache'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

this.blobFileContent = await response.blob();
urlFileContent = null;
} catch (error) {
console.error('[ADF DEBUG] Failed to fetch PDF as blob, falling back to URL', error);
}
}

this.mimeType = mimeType;
this.nodeMimeType = nodeMimeType;
this.fileName = versionData ? versionData.name : nodeData.name;
this.urlFileContent = urlFileContent + (this.cacheBusterNumber ? '&' + this.cacheBusterNumber : '');
this.urlFileContent = urlFileContent ? urlFileContent + (this.cacheBusterNumber ? '&' + this.cacheBusterNumber : '') : null;

Check warning on line 384 in lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested ternary operation into an independent statement.

See more on https://sonarcloud.io/project/issues?id=Alfresco_alfresco-ng2-components&issues=AZ1DruIpnyOtrsjoaG5m&open=AZ1DruIpnyOtrsjoaG5m&pullRequest=11657
this.sidebarRightTemplateContext.node = nodeData;
this.sidebarLeftTemplateContext.node = nodeData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ export class UserPreferencesService {

this.select('textOrientation').subscribe((direction: Direction) => {
renderer.setAttribute(this.document.body, 'dir', direction);
(this.directionality as any).value = direction;
this.directionality.valueSignal.set(direction);
this.directionality.change.emit(direction);
Comment on lines +138 to +139
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adds new behavior (mutating Directionality via valueSignal.set(...) and emitting change) but the existing unit tests only assert the dir attribute on the document. Please extend user-preferences.service.spec.ts to cover the Directionality update (e.g., verify the injected Directionality reflects the new direction and that change emits once).

Copilot generated this review using guidance from repository custom instructions.
});
}

Expand Down
1 change: 0 additions & 1 deletion lib/js-api/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export default {
preset: '../../jest.preset.js',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
collectCoverage: true,
coverageReporters: ['html', ['text-summary', { file: 'summary.txt' }], 'text-summary'],
coverageDirectory: '../../coverage/js-api',
moduleNameMapper: {
Expand Down
2 changes: 1 addition & 1 deletion lib/js-api/src/authentication/oauth2Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ export class Oauth2Auth extends AlfrescoApiClient {

if (!externalHash) {
hash = decodeURIComponent(window.location.hash);
if (!this.startWithHashRoute(hash)) {
if (hash && !this.startWithHashRoute(hash)) {
window.location.hash = '';
}
} else {
Expand Down
1 change: 0 additions & 1 deletion lib/js-api/src/utils/is-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@
* limitations under the License.
*/

// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
export const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.document !== 'undefined';
48 changes: 26 additions & 22 deletions lib/js-api/test/oauth2Auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,24 @@ describe('Oauth2 test', () => {
});

alfrescoJsApi.storage.setStorage(mockStorage);
Object.defineProperty(window, 'location', {
writable: true,
value: {
ancestorOrigins: null,
hash: null,
host: 'dummy.com',
port: '80',
protocol: 'http:',
hostname: 'dummy.com',
href: 'http://localhost/',
origin: 'dummy.com',
pathname: null,
search: null,
assign: (url: string) => {
window.location.href = url;
},
reload: null,
replace: null
}
});
delete (window as any).location;
(window as any).location = {
ancestorOrigins: null,
hash: null,
host: 'dummy.com',
port: '80',
protocol: 'http:',
hostname: 'dummy.com',
href: 'http://localhost/',
origin: 'dummy.com',
pathname: null,
search: null,
assign: jest.fn((url: string) => {
window.location.href = url;
}),
reload: jest.fn(),
replace: jest.fn()
};
});

afterEach(() => {
Expand Down Expand Up @@ -189,7 +187,6 @@ describe('Oauth2 test', () => {
});

it('should refresh token when the login not use the implicitFlow ', (done) => {
jest.spyOn(window, 'document', 'get').mockReturnValueOnce(undefined);
oauth2Mock.get200Response();

const oauth2Auth = new Oauth2Auth(
Expand All @@ -208,6 +205,10 @@ describe('Oauth2 test', () => {
alfrescoJsApi
);

jest.spyOn(oauth2Auth as any, 'silentRefresh').mockImplementation(function (this: any) {
this.pollingRefreshToken();
});

let calls = 0;
oauth2Auth.refreshToken = () => {
calls++;
Expand All @@ -224,7 +225,6 @@ describe('Oauth2 test', () => {
});

it('should not hang the app also if the logout is missing', (done) => {
jest.spyOn(window, 'document', 'get').mockReturnValueOnce(undefined);
oauth2Mock.get200Response();

const oauth2Auth = new Oauth2Auth(
Expand All @@ -244,6 +244,10 @@ describe('Oauth2 test', () => {
alfrescoJsApi
);

jest.spyOn(oauth2Auth as any, 'silentRefresh').mockImplementation(function (this: any) {
this.pollingRefreshToken();
});

let calls = 0;
oauth2Auth.refreshToken = () => {
calls++;
Expand Down
50 changes: 24 additions & 26 deletions lib/js-api/test/oauth2AuthImplicitFlow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,24 @@ describe('Oauth2 Implicit flow test', () => {
alfrescoJsApi = new AlfrescoApi({
hostEcm: ''
});
Object.defineProperty(window, 'location', {
writable: true,
value: {
ancestorOrigins: null,
hash: '',
host: 'dummy.com',
port: '80',
protocol: 'http:',
hostname: 'dummy.com',
href: 'http://localhost/',
origin: 'dummy.com',
pathname: null,
search: null,
assign: (url: string) => {
window.location.href = url;
},
reload: null,
replace: null
}
});
delete (window as any).location;
(window as any).location = {
ancestorOrigins: null,
hash: '',
host: 'dummy.com',
port: '80',
protocol: 'http:',
hostname: 'dummy.com',
href: 'http://localhost/',
origin: 'dummy.com',
pathname: null,
search: null,
assign: jest.fn((url: string) => {
window.location.href = url;
}),
reload: jest.fn(),
replace: jest.fn()
};
});

it('should throw an error if redirectUri is not present', (done) => {
Expand Down Expand Up @@ -84,8 +82,8 @@ describe('Oauth2 Implicit flow test', () => {
alfrescoJsApi
);

oauth2Auth.on('implicit_redirect', () => {
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
oauth2Auth.on('implicit_redirect', (href: string) => {
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
done();
});

Expand All @@ -110,8 +108,8 @@ describe('Oauth2 Implicit flow test', () => {
let setItemCalled = false;
alfrescoJsApi.storage.setItem = () => (setItemCalled = true);

oauth2Auth.on('implicit_redirect', () => {
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
oauth2Auth.on('implicit_redirect', (href: string) => {
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
assert.equal(setItemCalled, true);
done();
});
Expand Down Expand Up @@ -168,8 +166,8 @@ describe('Oauth2 Implicit flow test', () => {
let lastValues: [string, any];
alfrescoJsApi.storage.setItem = (key, value) => (lastValues = [key, value]);

oauth2Auth.on('implicit_redirect', () => {
assert.equal(window.location.href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
oauth2Auth.on('implicit_redirect', (href: string) => {
assert.equal(href.includes('https://myOauthUrl:30081/auth/realms/springboot/protocol/openid-connect/auth?'), true);
assert.deepEqual(lastValues, ['loginFragment', '/redirect-path&session_state=eqfqwfqwf']);
done();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@

import { FileViewerWidgetComponent } from './file-viewer.widget';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormFieldModel, FormModel, FormService, NoopAuthModule, NoopTranslateModule } from '@alfresco/adf-core';
import { FormFieldModel, FormModel, NoopAuthModule, NoopTranslateModule } from '@alfresco/adf-core';

describe('FileViewerWidgetComponent', () => {
const fakeForm = new FormModel();
let widget: FileViewerWidgetComponent;
let formServiceStub: Partial<FormService>;
let fixture: ComponentFixture<FileViewerWidgetComponent>;

const fakePngAnswer: any = {
Expand All @@ -42,11 +41,9 @@ describe('FileViewerWidgetComponent', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [NoopTranslateModule, NoopAuthModule, FileViewerWidgetComponent],
providers: [{ provide: FormService, useValue: formServiceStub }]
imports: [NoopTranslateModule, NoopAuthModule, FileViewerWidgetComponent]
});

formServiceStub = TestBed.inject(FormService);
fixture = TestBed.createComponent(FileViewerWidgetComponent);
widget = fixture.componentInstance;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ import { ProcessInstanceCloud } from '../../start-process/models/process-instanc

const PRESET_KEY = 'adf-cloud-process-list.presets';

/* eslint-disable @typescript-eslint/brace-style */

@Component({
selector: 'adf-cloud-process-list',
imports: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ const taskPresetsCloudDefaultModel = {
]
};

/* eslint-disable @typescript-eslint/brace-style */

@Directive()
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export abstract class BaseTaskListCloudComponent<T = unknown>
Expand Down
Loading