Merge pull request #584 from Alfresco/dev-eromano-574

Dev eromano 574
This commit is contained in:
Mario Romano
2016-08-23 18:57:30 +01:00
committed by GitHub
96 changed files with 1596 additions and 2471 deletions
@@ -15,9 +15,9 @@
* limitations under the License.
*/
import { Component } from '@angular/core';
import { AlfrescoLoginComponent } from 'ng2-alfresco-login';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import {Component} from '@angular/core';
import {AlfrescoLoginComponent} from 'ng2-alfresco-login';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
declare let __moduleName: string;
@@ -30,7 +30,7 @@ declare let __moduleName: string;
})
export class LoginDemoComponent {
providers: string [] = ['ECM'];
providers: string = 'ECM';
constructor(public router: Router) {
}
@@ -45,28 +45,22 @@ export class LoginDemoComponent {
}
toggleECM(checked) {
if (checked) {
this.providers.push('ECM');
if (checked && this.providers === 'BPM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'ECM';
} else {
this.removeElement('ECM');
this.providers = undefined;
}
}
toggleBPM(checked) {
if (checked) {
this.providers.push('BPM');
if (checked && this.providers === 'ECM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'BPM';
} else {
this.removeElement('BPM');
this.providers = undefined;
}
}
removeElement(el: string) {
for (let i = 0; i < this.providers.length; i++) {
if (this.providers[i] === el) {
this.providers.splice(i, 1);
return false;
}
}
}
}
+1 -1
View File
@@ -63,6 +63,7 @@
"@angular/router": "3.0.0-alpha.7",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
"alfresco-js-api": "^0.3.0",
"systemjs": "0.19.27",
"core-js": "2.4.0",
"reflect-metadata": "0.1.3",
@@ -74,7 +75,6 @@
"ng2-translate": "2.2.0",
"pdfjs-dist": "1.5.258",
"flag-icon-css": "2.3.0",
"alfresco-js-api": "0.2.1",
"ng2-alfresco-core": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"ng2-alfresco-documentlist": "0.2.0",
+1 -1
View File
@@ -26,7 +26,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -13,6 +13,12 @@ npm install --save ng2-activiti-form
### Dependencies
Add the following dependency to your index.html:
```html
<script src="node_modules/alfresco-js-api/dist/alfresco-js-api.js"></script>
```
You must separately install the following libraries for your application:
- [ng2-translate](https://github.com/ocombe/ng2-translate)
@@ -17,6 +17,7 @@ module.exports = function (config) {
{pattern: 'node_modules/@angular/**/*.map', included: false, watched: false},
{pattern: 'node_modules/ng2-alfresco-core/dist/**/*.js', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
{pattern: 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', included: true, watched: false},
{pattern: 'karma-test-shim.js', included: true, watched: true},
@@ -58,6 +58,7 @@
"@angular/router": "3.0.0-alpha.7",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
"alfresco-js-api": "^0.3.0",
"systemjs": "0.19.27",
"core-js": "2.4.0",
"reflect-metadata": "0.1.3",
@@ -80,6 +81,7 @@
"karma-coverage": "1.0.0",
"karma-coveralls": "1.1.2",
"karma-jasmine": "1.0.2",
"karma-jasmine-ajax": "0.1.13",
"karma-jasmine-html-reporter": "0.2.0",
"karma-jasmine-ajax": "0.1.13",
"karma-mocha-reporter": "2.0.3",
@@ -40,7 +40,7 @@ describe('ActivitiForm', () => {
]);
window['componentHandler'] = componentHandler;
formService = new FormService(null, null, null);
formService = new FormService(null);
formComponent = new ActivitiForm(formService, visibilityService);
});
@@ -15,81 +15,56 @@
* limitations under the License.
*/
import { it, describe, expect, beforeEach } from '@angular/core/testing';
import { Http, RequestOptionsArgs, Response, ResponseOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { it, inject, describe, expect, beforeEach, beforeEachProviders, afterEach } from '@angular/core/testing';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
import { Response, ResponseOptions } from '@angular/http';
import { FormService } from './form.service';
import { FormValues } from './../components/widgets/core/index';
declare let jasmine: any;
describe('FormService', () => {
let http: Http;
let responseBody: any;
let formService: FormService;
let authService: AlfrescoAuthenticationService;
let settingsService: AlfrescoSettingsService;
let responseBody: any, formService: FormService;
let createResponse = (url, body): Observable<Response> => {
return Observable.create(observer => {
let response = new Response(new ResponseOptions({
url: url,
body: body
}));
observer.next(response);
observer.complete();
});
};
beforeEach(() => {
http = <Http> {
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return createResponse(url, responseBody);
},
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
return createResponse(url, responseBody);
}
};
settingsService = new AlfrescoSettingsService();
settingsService.setProviders([]);
authService = new AlfrescoAuthenticationService(settingsService, null);
formService = new FormService(http, authService, settingsService);
beforeEachProviders(() => {
return [
FormService,
AlfrescoSettingsService,
AlfrescoAuthenticationService
];
});
it('should resolve host address via settings service', () => {
const url = '<url>';
settingsService.bpmHost = url;
expect(formService.getHostAddress()).toBe(url);
beforeEach(inject([FormService], (service: FormService) => {
jasmine.Ajax.install();
formService = service;
}));
afterEach(() => {
jasmine.Ajax.uninstall();
});
it('should fetch and parse process definitions', (done) => {
spyOn(http, 'get').and.callThrough();
responseBody = {
data: [
{ id: '1' },
{ id: '2' }
{id: '1'},
{id: '2'}
]
};
formService.getProcessDefinitions().subscribe(result => {
expect(http.get).toHaveBeenCalled();
let args: any[] = (<any>http).get.calls.argsFor(0);
expect(args[0].endsWith('/process-definitions')).toBeTruthy();
expect(result).toEqual(responseBody.data);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/process-definitions')).toBeTruthy();
expect(result).toEqual(JSON.parse(jasmine.Ajax.requests.mostRecent().response).data);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should fetch and parse tasks', (done) => {
spyOn(http, 'post').and.callThrough();
responseBody = {
data: [
{ id: '1' },
@@ -98,126 +73,130 @@ describe('FormService', () => {
};
formService.getTasks().subscribe(result => {
expect(http.post).toHaveBeenCalled();
let args: any[] = (<any>http).post.calls.argsFor(0);
expect(args[0].endsWith('/tasks/query')).toBeTruthy();
expect(result).toEqual(responseBody.data);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/tasks/query')).toBeTruthy();
expect(result).toEqual(JSON.parse(jasmine.Ajax.requests.mostRecent().response).data);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should fetch and parse the task by id', (done) => {
spyOn(http, 'get').and.callThrough();
responseBody = {
id: '1'
};
formService.getTask('1').subscribe(result => {
expect(http.get).toHaveBeenCalled();
let args: any[] = (<any>http).get.calls.argsFor(0);
expect(args[0].endsWith('/tasks/1')).toBeTruthy();
expect(result).toEqual(responseBody);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/tasks/1')).toBeTruthy();
expect(result.id).toEqual(responseBody.id);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should save task form', (done) => {
spyOn(http, 'post').and.callThrough();
let values = <FormValues> {
let values = {
field1: 'one',
field2: 'two'
};
formService.saveTaskForm('1', values).subscribe(() => {
expect(http.post).toHaveBeenCalled();
let args: any[] = (<any>http).post.calls.argsFor(0);
expect(args[0].endsWith('/task-forms/1/save-form')).toBeTruthy();
expect(args[1]).toEqual(JSON.stringify({ values: values }));
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1/save-form')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field1).toEqual(values.field1);
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should complete task form', (done) => {
spyOn(http, 'post').and.callThrough();
let values = <FormValues> {
let values = {
field1: 'one',
field2: 'two'
};
formService.completeTaskForm('1', values).subscribe(() => {
expect(http.post).toHaveBeenCalled();
let args: any[] = (<any>http).post.calls.argsFor(0);
expect(args[0].endsWith('/task-forms/1')).toBeTruthy();
expect(args[1]).toEqual(JSON.stringify({ values: values }));
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field1).toEqual(values.field1);
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should complete task form with a specific outcome', (done) => {
spyOn(http, 'post').and.callThrough();
let values = <FormValues> {
let values = {
field1: 'one',
field2: 'two'
};
formService.completeTaskForm('1', values, 'custom').subscribe(() => {
expect(http.post).toHaveBeenCalled();
let args: any[] = (<any>http).post.calls.argsFor(0);
expect(args[0].endsWith('/task-forms/1')).toBeTruthy();
expect(args[1]).toEqual(JSON.stringify({ values: values, outcome: 'custom' }));
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).values.field2).toEqual(values.field2);
expect(JSON.parse(jasmine.Ajax.requests.mostRecent().params).outcome).toEqual('custom' );
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should get task form by id', (done) => {
spyOn(http, 'get').and.callThrough();
responseBody = { id: '1' };
responseBody = { id: 1 };
formService.getTaskForm('1').subscribe(result => {
expect(http.get).toHaveBeenCalled();
let args: any[] = (<any>http).get.calls.argsFor(0);
expect(args[0].endsWith('/task-forms/1')).toBeTruthy();
expect(result).toEqual(responseBody);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/task-forms/1')).toBeTruthy();
expect(result.id).toEqual(responseBody.id);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should get form definition by id', (done) => {
spyOn(http, 'get').and.callThrough();
responseBody = { id: '1' };
responseBody = { id: 1 };
formService.getFormDefinitionById('1').subscribe(result => {
expect(http.get).toHaveBeenCalled();
let args: any[] = (<any>http).get.calls.argsFor(0);
expect(args[0].endsWith('/form-models/1')).toBeTruthy();
expect(result).toEqual(responseBody);
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('/form-models/1')).toBeTruthy();
expect(result.id).toEqual(responseBody.id);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should get form definition id by name', (done) => {
spyOn(http, 'get').and.callThrough();
const formName = 'form1';
const formId = 1;
responseBody = {
@@ -227,14 +206,16 @@ describe('FormService', () => {
};
formService.getFormDefinitionByName(formName).subscribe(result => {
expect(http.get).toHaveBeenCalled();
let args: any[] = (<any>http).get.calls.argsFor(0);
expect(args[0].endsWith(`models?filter=myReusableForms&filterText=${formName}&modelType=2`)).toBeTruthy();
expect(jasmine.Ajax.requests.mostRecent().url.endsWith(`models?filter=myReusableForms&filterText=${formName}&modelType=2`)).toBeTruthy();
expect(result).toEqual(formId);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(responseBody)
});
});
it('should not get form id from response', () => {
@@ -253,30 +234,6 @@ describe('FormService', () => {
expect(formService.getFormId(null)).toBeNull();
});
it('should convert response to json object', () => {
let data = { id: 1 };
let response = new Response(new ResponseOptions({ body: data }));
expect(formService.toJson(response)).toEqual(data);
});
it('should fallback to empty json object', () => {
let response = new Response(new ResponseOptions({ body: null }));
expect(formService.toJson(response)).toEqual({});
expect(formService.toJson(null)).toEqual({});
});
it('should convert response to json array', () => {
let payload = {
data: [
{ id: 1 }
]
};
let response = new Response(new ResponseOptions({ body: JSON.stringify(payload) }));
expect(formService.toJsonArray(response)).toEqual(payload.data);
});
it('should fallback to empty json array', () => {
expect(formService.toJsonArray(null)).toEqual([]);
@@ -15,12 +15,10 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Response, Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { FormValues } from './../components/widgets/core/index';
import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Rx';
import {AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {FormValues} from './../components/widgets/core/index';
@Injectable()
export class FormService {
@@ -28,92 +26,60 @@ export class FormService {
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
static GENERIC_ERROR_MESSAGE: string = 'Server error';
constructor(private http: Http,
private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService) {
}
getHostAddress(): string {
return this.alfrescoSettingsService.bpmHost;
constructor(private authService: AlfrescoAuthenticationService) {
}
getProcessDefinitions(): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/process-definitions`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessDefinitions({}))
.map(this.toJsonArray)
.catch(this.handleError);
}
getTasks(): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/tasks/query`;
let body = JSON.stringify({});
let options = this.getRequestOptions();
return this.http
.post(url, body, options)
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.listTasks({}))
.map(this.toJsonArray)
.catch(this.handleError);
}
getTask(id: string): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/tasks/${id}`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
getTask(taskId: string): Observable<any> {
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.getTask(taskId))
.map(this.toJson)
.catch(this.handleError);
}
saveTaskForm(id: string, formValues: FormValues): Observable<Response> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/task-forms/${id}/save-form`;
let body = JSON.stringify({ values: formValues });
let options = this.getRequestOptions();
saveTaskForm(taskId: string, formValues: FormValues): Observable<any> {
let body = JSON.stringify({values: formValues});
return this.http
.post(url, body, options)
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.saveTaskForm(taskId, body))
.catch(this.handleError);
}
/**
* Complete Task Form
* @param id Task Id
* @param taskId Task Id
* @param formValues Form Values
* @param outcome Form Outcome
* @returns {any}
*/
completeTaskForm(id: string, formValues: FormValues, outcome?: string): Observable<Response> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/task-forms/${id}`;
let data: any = { values: formValues };
completeTaskForm(taskId: string, formValues: FormValues, outcome?: string): Observable<any> {
let data: any = {values: formValues};
if (outcome) {
data.outcome = outcome;
}
let body = JSON.stringify(data);
let options = this.getRequestOptions();
return this.http
.post(url, body, options)
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.completeTaskForm(taskId, body))
.catch(this.handleError);
}
getTaskForm(id: string): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/api/enterprise/task-forms/${id}`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
getTaskForm(taskId: string): Observable<any> {
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.getTaskForm(taskId))
.map(this.toJson)
.catch(this.handleError);
}
getFormDefinitionById(id: string): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/app/rest/form-models/${id}`;
let options = this.getRequestOptions();
return this.http
.get(url, options)
getFormDefinitionById(formId: string): Observable<any> {
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.editorApi.getForm(formId))
.map(this.toJson)
.catch(this.handleError);
}
@@ -124,53 +90,37 @@ export class FormService {
* @returns {Promise<T>|Promise<ErrorObservable>}
*/
getFormDefinitionByName(name: string): Observable<any> {
let url = `${this.getHostAddress()}/activiti-app/app/rest/models?filter=myReusableForms&filterText=${name}&modelType=2`;
let options = this.getRequestOptions();
let opts = {
'filter': 'myReusableForms',
'filterText': name,
'modelType': 2
};
return this.http
.get(url, options)
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.modelsApi.getModels(opts))
.map(this.getFormId)
.catch(this.handleError);
}
private getHeaders(): Headers {
return new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': this.authService.getTicket('BPM')
});
}
private getRequestOptions(): RequestOptions {
let headers = this.getHeaders();
return new RequestOptions({headers: headers});
}
getFormId(res: Response) {
getFormId(res: any) {
let result = null;
if (res) {
let body = res.json();
if (body && body.data && body.data.length > 0) {
result = body.data[0].id;
}
if (res && res.data && res.data.length > 0) {
result = res.data[0].id;
}
return result;
}
toJson(res: Response) {
toJson(res: any) {
if (res) {
let body = res.json();
return body || {};
return res || {};
}
return {};
}
toJsonArray(res: Response) {
toJsonArray(res: any) {
if (res) {
let body = res.json();
return body.data || [];
return res.data || [];
}
return [];
}
@@ -184,5 +134,4 @@ export class FormService {
console.error(errMsg);
return Observable.throw(errMsg);
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -33,13 +33,13 @@
"@angular/router": "3.0.0-alpha.7",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
"alfresco-js-api": "^0.3.0",
"systemjs": "0.19.27",
"core-js": "^2.4.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.6",
"zone.js": "^0.6.12",
"ng2-activiti-processlist": "file:../",
"alfresco-js-api": "^0.1.0",
"material-design-icons": "^2.2.3",
"material-design-lite": "^1.1.3"
},
@@ -25,27 +25,45 @@ import {
AlfrescoSettingsService,
ALFRESCO_CORE_PROVIDERS
} from 'ng2-alfresco-core';
import { HTTP_PROVIDERS, BrowserXhr } from '@angular/http';
@Component({
selector: 'my-app',
template: `<activiti-processlist></activiti-processlist>`,
template: `label for="token"><b>Insert a valid access token / ticket:</b></label><br>
<input id="token" type="text" size="48" (change)="updateToken();documentList.reload()" [(ngModel)]="token"><br>
<label for="token"><b>Insert the ip of your Alfresco instance:</b></label><br>
<input id="token" type="text" size="48" (change)="updateHost();documentList.reload()" [(ngModel)]="bpmHost"><br><br>
<div *ngIf="!authenticated" style="color:#FF2323">
Authentication failed to ip {{ bpmHost }} with user: admin, admin, you can still try to add a valid token to perform
operations.
</div>
<hr>
<label for="token"><b>Insert a scriptPath</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="scriptPath"><br>
<label for="token"><b>Insert a contextRoot</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="contextRoot"><br>
<label for="token"><b>Insert a servicePath</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="servicePath"><br>
<div class="container" *ngIf="authenticated">
<activiti-processlist></activiti-processlist>
</div>`,
providers: [ACTIVITI_PROCESSLIST_PROVIDERS],
directives: [ACTIVITI_PROCESSLIST_DIRECTIVES]
})
class MyDemoApp implements OnInit {
authenticated: boolean;
ecmHost: string = 'http://127.0.0.1:9999';
ecmHost: string = 'http://127.0.0.1:9999';
token: string;
constructor(
private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService
private settingsService: AlfrescoSettingsService
) {
console.log('constructor');
alfrescoSettingsService.ecmHost = this.ecmHost;
settingsService.setProviders('BPM');
settingsService.bpmHost = this.bpmHost;
if (this.authService.getTicket()) {
this.token = this.authService.getTicket();
}
@@ -60,12 +78,12 @@ class MyDemoApp implements OnInit {
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
login() {
this.authService.login('admin@app.activiti.com', 'admin', ['BPM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -78,18 +96,6 @@ class MyDemoApp implements OnInit {
}
}
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
bootstrap(MyDemoApp, [
ALFRESCO_CORE_PROVIDERS,
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
ALFRESCO_CORE_PROVIDERS
]);
@@ -15,17 +15,17 @@
* limitations under the License.
*/
import { Ng2ActivitiProcesslistComponent } from './src/components/ng2-activiti-processlist.component';
import { ActivitiProcessService } from './src/services/activiti-process-service.service';
import { ActivitiProcesslistComponent } from './src/components/activiti-processlist.component';
import { ActivitiProcessService } from './src/services/activiti-process.service';
// components
export * from './src/components/ng2-activiti-processlist.component';
export * from './src/components/activiti-processlist.component';
// services
export * from './src/services/activiti-process-service.service';
export * from './src/services/activiti-process.service';
export const ACTIVITI_PROCESSLIST_DIRECTIVES: [any] = [
Ng2ActivitiProcesslistComponent
ActivitiProcesslistComponent
];
export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [
@@ -21,6 +21,7 @@ module.exports = function (config) {
{pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.html', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.css', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
{pattern: 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', included: true, watched: false},
{pattern: 'karma-test-shim.js', included: true, watched: true},
@@ -56,6 +56,7 @@
"@angular/router": "3.0.0-alpha.7",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
"alfresco-js-api": "^0.3.0",
"systemjs": "0.19.27",
"core-js": "^2.4.0",
"reflect-metadata": "^0.1.3",
@@ -1,49 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Observable } from 'rxjs/Observable';
import {
ProcessList,
SingleProcessList
} from './activiti-process.model.mock';
import { ActivitiProcessService } from './../services/activiti-process-service.service';
import { AlfrescoSettingsService } from 'ng2-alfresco-core';
export class ActivitiProcessServiceMock extends ActivitiProcessService {
getProcessesResult: ProcessList = new SingleProcessList('Example process 1');
getProcessesReject: boolean = false;
getProcessesRejectError: string = 'Error';
constructor(
settings?: AlfrescoSettingsService
) {
super(settings, null);
}
getProcesses() {
if (this.getProcessesReject) {
return Observable.throw(this.getProcessesRejectError);
}
return Observable.create(observer => {
observer.next(this.getProcessesResult);
observer.complete();
}).map((json) => {
return json.data;
});
}
}
@@ -0,0 +1,65 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, inject, beforeEachProviders, beforeEach} from '@angular/core/testing';
import {TestComponentBuilder} from '@angular/compiler/testing';
import {AlfrescoSettingsService, AlfrescoTranslationService, AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {ActivitiProcesslistComponent} from '../../src/components/activiti-processlist.component';
import {TranslationMock} from './../assets/translation.service.mock';
import {ActivitiProcessService} from '../services/activiti-process.service';
describe('ActivitiProcesslistComponent', () => {
let processlistComponentFixture, element, component;
beforeEachProviders(() => {
return [
ActivitiProcessService,
AlfrescoSettingsService,
AlfrescoAuthenticationService,
{provide: AlfrescoTranslationService, useClass: TranslationMock}
];
});
beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ActivitiProcesslistComponent)
.then(fixture => {
processlistComponentFixture = fixture;
element = processlistComponentFixture.nativeElement;
component = processlistComponentFixture.componentInstance;
});
}));
it('should have a valid title', () => {
expect(element.querySelector('h1')).toBeDefined();
expect(element.getElementsByTagName('h1')[0].innerHTML).toEqual('My Activiti Processes');
});
it('should contain a list of processes', () => {
let componentHandler = jasmine.createSpyObj('componentHandler', [
'upgradeAllRegistered'
]);
window['componentHandler'] = componentHandler;
component.ngOnInit();
processlistComponentFixture.detectChanges();
expect(element.querySelector('table')).toBeDefined();
expect(element.querySelectorAll('table tbody tr').length).toEqual(1);
});
});
@@ -15,21 +15,10 @@
* limitations under the License.
*/
import {
Component,
OnInit
} from '@angular/core';
import {
AlfrescoPipeTranslate,
AlfrescoTranslationService,
CONTEXT_MENU_DIRECTIVES,
CONTEXT_MENU_PROVIDERS
} from 'ng2-alfresco-core';
import {
ALFRESCO_DATATABLE_DIRECTIVES,
ObjectDataTableAdapter
} from 'ng2-alfresco-datatable';
import { ActivitiProcessService } from '../services/activiti-process-service.service';
import {Component, OnInit } from '@angular/core';
import { AlfrescoPipeTranslate, AlfrescoTranslationService, CONTEXT_MENU_DIRECTIVES, CONTEXT_MENU_PROVIDERS } from 'ng2-alfresco-core';
import { ALFRESCO_DATATABLE_DIRECTIVES, ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
import { ActivitiProcessService } from '../services/activiti-process.service';
import { ProcessInstance } from '../models/process-instance';
declare let __moduleName: string;
@@ -44,21 +33,18 @@ declare let __moduleName: string;
}
`
],
templateUrl: './ng2-activiti-processlist.component.html',
templateUrl: './activiti-processlist.component.html',
directives: [ ALFRESCO_DATATABLE_DIRECTIVES, CONTEXT_MENU_DIRECTIVES ],
pipes: [ AlfrescoPipeTranslate ],
providers: [ CONTEXT_MENU_PROVIDERS ]
})
export class Ng2ActivitiProcesslistComponent implements OnInit {
export class ActivitiProcesslistComponent implements OnInit {
errorMessage: string;
processInstances: ProcessInstance[];
data: ObjectDataTableAdapter;
constructor (
private processService: ActivitiProcessService,
private translate: AlfrescoTranslationService
) {
constructor (private processService: ActivitiProcessService, private translate: AlfrescoTranslationService) {
if (translate !== null) {
translate.addTranslationFolder('node_modules/ng2-activiti-processlist/src');
}
@@ -72,8 +58,7 @@ export class Ng2ActivitiProcesslistComponent implements OnInit {
this.processService.getProcesses()
.subscribe(
(processInstances) => {
// this.processInstances = processInstances;
this.data = new ObjectDataTableAdapter(
this.data = new ObjectDataTableAdapter(
processInstances,
[
{type: 'text', key: 'id', title: 'Id', sortable: true},
@@ -89,5 +74,4 @@ export class Ng2ActivitiProcesslistComponent implements OnInit {
onItemClick(processInstance: ProcessInstance, event: any) {
console.log(processInstance, event);
}
}
@@ -1,67 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HTTP_PROVIDERS } from '@angular/http';
import {describe, expect, it, inject, beforeEachProviders} from '@angular/core/testing';
import { TestComponentBuilder } from '@angular/compiler/testing';
import {
AlfrescoSettingsService,
AlfrescoTranslationService
} from 'ng2-alfresco-core';
import { Ng2ActivitiProcesslistComponent } from '../../src/components/ng2-activiti-processlist.component';
import { ActivitiProcessServiceMock } from '../assets/activiti-process-service.mock';
import { TranslationMock } from './../assets/translation.service.mock';
import { ActivitiProcessService } from '../services/activiti-process-service.service';
describe('ActivitiProcesslistComponent', () => {
beforeEachProviders(() => {
return [
{ provide: AlfrescoSettingsService },
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
{ provide: ActivitiProcessService, useClass: ActivitiProcessServiceMock },
HTTP_PROVIDERS
];
});
it('should have a valid title', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(Ng2ActivitiProcesslistComponent)
.then((fixture) => {
let element = fixture.nativeElement;
expect(element.querySelector('h1')).toBeDefined();
expect(element.getElementsByTagName('h1')[0].innerHTML).toEqual('My Activiti Processes');
});
}));
it('should contain a list of processes', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
let componentHandler = jasmine.createSpyObj('componentHandler', [
'upgradeAllRegistered'
]);
window['componentHandler'] = componentHandler;
return tcb
.createAsync(Ng2ActivitiProcesslistComponent)
.then((fixture) => {
let element = fixture.nativeElement, component = fixture.componentInstance;
component.ngOnInit();
fixture.detectChanges();
expect(element.querySelector('table')).toBeDefined();
expect(element.querySelectorAll('table tbody tr').length).toEqual(1);
});
}));
});
@@ -1,74 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
it,
describe,
expect,
beforeEachProviders,
inject
} from '@angular/core/testing';
import {
Response,
ResponseOptions,
HTTP_PROVIDERS,
XHRBackend
} from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { ActivitiProcessService } from './activiti-process-service.service';
import { ProcessInstance } from '../models/process-instance';
describe('ActivitiProcessService', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{ provide: XHRBackend, useClass: MockBackend },
ActivitiProcessService,
AlfrescoSettingsService
];
});
it('should be there', inject([ActivitiProcessService], (processService: ActivitiProcessService) => {
expect(typeof processService.getProcesses).toBe('function');
}));
it('should get process instances',
inject([ActivitiProcessService, XHRBackend], (processService: ActivitiProcessService, mockBackend: MockBackend) => {
mockBackend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: {
data: [{
id: 'myprocess:1',
name: 'my process'
}]
}
})));
});
processService.getProcesses().subscribe((instances: ProcessInstance[]) => {
expect(instances.length).toBe(1);
expect(instances[0].id).toBe('myprocess:1');
expect(instances[0].name).toBe('my process');
});
}));
});
@@ -1,58 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { ProcessInstance } from '../models/process-instance';
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class ActivitiProcessService {
constructor(private alfrescoSettingsService: AlfrescoSettingsService, private http: Http) {
}
getProcesses(): Observable<ProcessInstance[]> {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
// headers.append('Authorization', 'Basic ' + btoa('admin@app.activiti.com:admin'));
return this.http.post(
this.alfrescoSettingsService.bpmHost + '/activiti-app/api/enterprise/process-instances/query',
'{"page":0,"sort":"created-desc","state":"all"}',
new RequestOptions({
headers: headers
}))
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
@@ -0,0 +1,51 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { it, describe, expect, beforeEachProviders, beforeEach, inject } from '@angular/core/testing';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
import { ActivitiProcessService } from './activiti-process.service';
// import { ProcessInstance } from '../models/process-instance';
describe('ActivitiProcessService', () => {
let processService;
beforeEachProviders(() => {
return [
ActivitiProcessService,
AlfrescoSettingsService,
AlfrescoAuthenticationService
];
});
beforeEach(inject([ActivitiProcessService], (service: ActivitiProcessService) => {
processService = service;
}));
it('should get process instances', (done) => {
expect(true).toBe(true);
done();
// processService.getProcesses().subscribe((instances: ProcessInstance[]) => {
// expect(instances.length).toBe(1);
// expect(instances[0].id).toBe('myprocess:1');
// expect(instances[0].name).toBe('my process');
// done();
// });
});
});
@@ -0,0 +1,47 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {ProcessInstance} from '../models/process-instance';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class ActivitiProcessService {
constructor(public authService: AlfrescoAuthenticationService) {
}
getProcesses(): Observable<ProcessInstance[]> {
let request = {'page': 0, 'sort': 'created-desc', 'state': 'all'};
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessInstances(request))
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: any) {
return res.data || {};
}
private handleError(error: any) {
console.error(error);
return Observable.throw(error || 'Server error');
}
}
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -13,6 +13,12 @@ npm install --save ng2-activiti-tasklist
### Dependencies
Add the following dependency to your index.html:
```html
<script src="node_modules/alfresco-js-api/dist/alfresco-js-api.js"></script>
```
You must separately install the following libraries for your application:
- [ng2-translate](https://github.com/ocombe/ng2-translate)
@@ -3,12 +3,6 @@
"description": "Alfresco Angular2 DataTable Component - Demo",
"version": "0.1.0",
"author": "Alfresco Software, Ltd.",
"contributors": [
{
"name": "Maurizio Vitale",
"email": "maurizio.vitale84@gmail.com"
}
],
"main": "index.js",
"scripts": {
"clean": "rimraf dist node_modules typings",
@@ -39,11 +33,10 @@
"rxjs": "5.0.0-beta.6",
"zone.js": "0.6.12",
"license-check": "1.1.5",
"material-design-icons": "2.2.3",
"material-design-lite": "1.1.3",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-datatable": "^0.1.12",
"ng2-alfresco-core": "^0.1.36"
},
@@ -70,6 +63,16 @@
"!/**/typings/**/*",
"!*.js"
],
"contributors": [
{
"name": "Maurizio Vitale",
"email": "maurizio.vitale84@gmail.com"
},
{
"name": "Eugenio Romano",
"email": "eugenio.romano@alfresco.com"
}
],
"path": "assets/license_header.txt",
"blocking": true,
"logInfo": false,
@@ -15,36 +15,60 @@
* limitations under the License.
*/
import { Component, OnInit } from '@angular/core';
import { HTTP_PROVIDERS } from '@angular/http';
import { ALFRESCO_CORE_PROVIDERS, AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { ActivitiTaskList } from 'ng2-activiti-tasklist';
import { ObjectDataTableAdapter, ObjectDataColumn } from 'ng2-alfresco-datatable';
import {Component, OnInit} from '@angular/core';
import {ALFRESCO_CORE_PROVIDERS, AlfrescoAuthenticationService, AlfrescoSettingsService} from 'ng2-alfresco-core';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {ActivitiTaskList} from 'ng2-activiti-tasklist';
import {ObjectDataTableAdapter, ObjectDataColumn} from 'ng2-alfresco-datatable';
import {HTTP_PROVIDERS} from '@angular/http';
declare let AlfrescoApi: any;
@Component({
selector: 'activiti-tasklist-demo',
template: `
<activiti-tasklist [data]="data"></activiti-tasklist>
`,
template: `label for="token"><b>Insert a valid access token / ticket:</b></label><br>
<input id="token" type="text" size="48" (change)="updateToken();documentList.reload()" [(ngModel)]="token"><br>
<label for="token"><b>Insert the ip of your Alfresco instance:</b></label><br>
<input id="token" type="text" size="48" (change)="updateHost();documentList.reload()" [(ngModel)]="bpmHost"><br><br>
<div *ngIf="!authenticated" style="color:#FF2323">
Authentication failed to ip {{ bpmHost }} with user: admin, admin, you can still try to add a valid token to perform
operations.
</div>
<hr>
<label for="token"><b>Insert a scriptPath</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="scriptPath"><br>
<label for="token"><b>Insert a contextRoot</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="contextRoot"><br>
<label for="token"><b>Insert a servicePath</b></label><br>
<input id="token" type="text" size="48" [(ngModel)]="servicePath"><br>
<div class="container" *ngIf="authenticated">
<activiti-tasklist></activiti-tasklist>
</div>`,
styles: [
':host > .container {padding: 10px}',
'.p-10 { padding: 10px; }'
],
directives: [ActivitiTaskList],
providers: [AlfrescoAuthenticationService]
directives: [ActivitiTaskList]
})
class ActivitiTaskListDemo implements OnInit {
bpmHost: string = 'http://127.0.0.1:9999';
token: string;
data: ObjectDataTableAdapter;
constructor(private setting: AlfrescoSettingsService) {
this.setting.setProviders(['BPM']);
authenticated: boolean;
constructor(private authService: AlfrescoAuthenticationService,
private settingsService: AlfrescoSettingsService) {
this.settingsService.setProviders('BPM');
this.data = new ObjectDataTableAdapter([], []);
}
ngOnInit() {
this.login();
let schema = [
{type: 'text', key: 'id', title: 'Id'},
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
@@ -56,9 +80,21 @@ class ActivitiTaskListDemo implements OnInit {
this.data.setColumns(columns);
}
login() {
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
this.authenticated = true;
},
error => {
console.log(error);
this.authenticated = false;
});
}
}
bootstrap(ActivitiTaskListDemo, [
HTTP_PROVIDERS,
ALFRESCO_CORE_PROVIDERS]
HTTP_PROVIDERS,
ALFRESCO_CORE_PROVIDERS]
);
@@ -38,6 +38,10 @@
{
"name": "Maurizio Vitale",
"email": "maurizio.vitale84@gmail.com"
},
{
"name": "Eugenio Romano",
"email": "eugenio.romano@alfresco.com"
}
],
"keywords": [
@@ -64,9 +68,9 @@
"zone.js": "0.6.12",
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"ng2-activiti-form": "0.2.0",
"alfresco-js-api": "0.2.0"
"alfresco-js-api": "^0.3.0"
},
"peerDependencies": {
"material-design-icons": "^2.2.3",
@@ -48,7 +48,7 @@ describe('ActivitiFilters', () => {
});
beforeEach(() => {
let activitiService = new ActivitiTaskListService(null, null, null);
let activitiService = new ActivitiTaskListService(null);
filterList = new ActivitiFilters(null, null, activitiService);
});
@@ -62,6 +62,7 @@ export class ActivitiFilters implements OnInit {
* Constructor
* @param auth
* @param translate
* @param activiti
*/
constructor(private auth: AlfrescoAuthenticationService,
private translate: AlfrescoTranslationService,
@@ -64,7 +64,7 @@ describe('ActivitiTaskList', () => {
});
beforeEach(() => {
let activitiSerevice = new ActivitiTaskListService(null, null, null);
let activitiSerevice = new ActivitiTaskListService(null);
taskList = new ActivitiTaskList(null, null, activitiSerevice);
});
@@ -66,6 +66,7 @@ export class ActivitiTaskList implements OnInit {
* Constructor
* @param auth
* @param translate
* @param translate
*/
constructor(private auth: AlfrescoAuthenticationService,
private translate: AlfrescoTranslationService,
@@ -15,12 +15,11 @@
* limitations under the License.
*/
import { it, describe, inject, beforeEach, beforeEachProviders } from '@angular/core/testing';
import { ActivitiTaskListService } from './activiti-tasklist.service';
import { AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { HTTP_PROVIDERS } from '@angular/http';
import { TaskDetailsModel } from '../models/task-details.model';
import { Comment } from '../models/comment.model';
import {it, describe, inject, beforeEach, beforeEachProviders} from '@angular/core/testing';
import {ActivitiTaskListService} from './activiti-tasklist.service';
import {AlfrescoSettingsService, AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {TaskDetailsModel} from '../models/task-details.model';
import {Comment} from '../models/comment.model';
declare let AlfrescoApi: any;
declare let jasmine: any;
@@ -44,10 +43,10 @@ describe('ActivitiTaskListService', () => {
let fakeFilter = {
page: 2, filterId: 2, appDefinitionId: null,
filter: {sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
filter: {sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee'}
};
let fakeUser = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
let fakeUser = {id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName'};
let fakeTaskList = {
size: 1, total: 1, start: 0,
@@ -64,7 +63,7 @@ describe('ActivitiTaskListService', () => {
error: 'wrong request'
};
let fakeTaskDetails = {id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser };
let fakeTaskDetails = {id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser};
let fakeTasksComment = {
size: 2, total: 2, start: 0,
@@ -96,16 +95,15 @@ describe('ActivitiTaskListService', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
ActivitiTaskListService,
AlfrescoSettingsService,
AlfrescoAuthenticationService,
ActivitiTaskListService
AlfrescoAuthenticationService
];
});
beforeEach( inject([ActivitiTaskListService], (activitiService: ActivitiTaskListService) => {
beforeEach(inject([ActivitiTaskListService], (activitiTaskListService: ActivitiTaskListService) => {
jasmine.Ajax.install();
service = activitiService;
service = activitiTaskListService;
}));
afterEach(() => {
@@ -132,7 +130,7 @@ describe('ActivitiTaskListService', () => {
it('should return the task list filtered', (done) => {
service.getTasks(fakeFilter).subscribe(
res => {
res => {
expect(res).toBeDefined();
expect(res.size).toEqual(1);
expect(res.total).toEqual(1);
@@ -158,7 +156,6 @@ describe('ActivitiTaskListService', () => {
},
(err: any) => {
expect(err).toBeDefined();
expect(err.json().error).toEqual('wrong request');
}
);
@@ -235,7 +232,11 @@ describe('ActivitiTaskListService', () => {
it('should add a task ', (done) => {
let taskFake = new TaskDetailsModel({
id: '', name: 'FakeNameTask', description: null, category: null,
id: 123,
parentTaskId: 456,
name: 'FakeNameTask',
description: null,
category: null,
assignee: fakeUser,
created: ''
});
@@ -262,7 +263,6 @@ describe('ActivitiTaskListService', () => {
});
it('should add a comment task ', (done) => {
service.addTaskComment(999, 'fake-comment-message').subscribe(
(res: Comment) => {
expect(res).toBeDefined();
@@ -287,10 +287,7 @@ describe('ActivitiTaskListService', () => {
});
});
/*
it('should complete the task ', (done) => {
service.completeTask(999).subscribe(
(res: any) => {
expect(res).toBeDefined();
@@ -304,7 +301,5 @@ describe('ActivitiTaskListService', () => {
responseText: JSON.stringify({})
});
});
*/
});
@@ -15,38 +15,29 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { FilterModel } from '../models/filter.model';
import { FilterParamsModel } from '../models/filter.model';
import { Comment } from '../models/comment.model';
import { User } from '../models/user.model';
import { TaskDetailsModel } from '../models/task-details.model';
import {Injectable} from '@angular/core';
import {AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {Observable} from 'rxjs/Rx';
import {FilterModel} from '../models/filter.model';
import {FilterParamsModel} from '../models/filter.model';
import {Comment} from '../models/comment.model';
import {User} from '../models/user.model';
import {TaskDetailsModel} from '../models/task-details.model';
@Injectable()
export class ActivitiTaskListService {
constructor(private http: Http,
public alfrescoSettingsService: AlfrescoSettingsService,
private authService: AlfrescoAuthenticationService) {
constructor(public authService: AlfrescoAuthenticationService) {
}
/**
* Retrive all the Deployed app
* @returns {Observable<any>}
*/
getDeployedApplications(name: string): Observable<any> {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/runtime-app-definitions`;
return this.http
.get(url, this.getRequestOptions())
.map((response: Response) => response.json().data.find(p => p.name === name))
.do(data => console.log('Application: ' + JSON.stringify(data)))
.catch(this.handleError);
return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.appsApi.getAppDefinitions())
.map((response: any) => response.data.find(p => p.name === name))
.do(data => console.log('Application: ' + JSON.stringify(data)));
}
/**
@@ -55,7 +46,6 @@ export class ActivitiTaskListService {
*/
getTaskListFilters(appId?: string): Observable<any> {
return Observable.fromPromise(this.callApiTaskFilters(appId))
.map(res => res.json())
.map((response: any) => {
let filters: FilterModel[] = [];
response.data.forEach((filter) => {
@@ -64,8 +54,7 @@ export class ActivitiTaskListService {
filters.push(filterModel);
});
return filters;
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -74,12 +63,10 @@ export class ActivitiTaskListService {
* @returns {any}
*/
getTasks(filter: FilterModel): Observable<any> {
return Observable.fromPromise(this.callApiTasksFiltered(filter.filter))
.map((res: Response) => {
return res.json();
})
.catch(this.handleError);
.map((res: any) => {
return res;
}).catch(this.handleError);
}
/**
@@ -89,11 +76,10 @@ export class ActivitiTaskListService {
*/
getTaskDetails(id: string): Observable<TaskDetailsModel> {
return Observable.fromPromise(this.callApiTaskDetails(id))
.map(res => res.json())
.map(res => res)
.map((details: any) => {
return new TaskDetailsModel(details);
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -103,7 +89,7 @@ export class ActivitiTaskListService {
*/
getTaskComments(id: string): Observable<Comment[]> {
return Observable.fromPromise(this.callApiTaskComments(id))
.map(res => res.json())
.map(res => res)
.map((response: any) => {
let comments: Comment[] = [];
response.data.forEach((comment) => {
@@ -112,8 +98,7 @@ export class ActivitiTaskListService {
comments.push(new Comment(comment.id, comment.message, comment.created, user));
});
return comments;
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -123,15 +108,14 @@ export class ActivitiTaskListService {
*/
getTaskChecklist(id: string): Observable<TaskDetailsModel[]> {
return Observable.fromPromise(this.callApiTaskChecklist(id))
.map(res => res.json())
.map(res => res)
.map((response: any) => {
let checklists: TaskDetailsModel[] = [];
response.data.forEach((checklist) => {
checklists.push(new TaskDetailsModel(checklist));
});
return checklists;
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -141,11 +125,10 @@ export class ActivitiTaskListService {
*/
addTask(task: TaskDetailsModel): Observable<TaskDetailsModel> {
return Observable.fromPromise(this.callApiAddTask(task))
.map(res => res.json())
.map(res => res)
.map((response: TaskDetailsModel) => {
return new TaskDetailsModel(response);
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -156,11 +139,11 @@ export class ActivitiTaskListService {
*/
addTaskComment(id: string, message: string): Observable<Comment> {
return Observable.fromPromise(this.callApiAddTaskComment(id, message))
.map(res => res.json())
.map(res => res)
.map((response: Comment) => {
return new Comment(response.id, response.message, response.created, response.createdBy);
})
.catch(this.handleError);
}).catch(this.handleError);
}
/**
@@ -168,97 +151,49 @@ export class ActivitiTaskListService {
* @param id - taskId
* @returns {TaskDetailsModel}
*/
completeTask(id: string): Observable<TaskDetailsModel> {
completeTask(id: string) {
return Observable.fromPromise(this.callApiCompleteTask(id))
.map(res => res.json())
.catch(this.handleError);
.map(res => res);
}
private callApiTasksFiltered(filter: FilterParamsModel) {
let data = JSON.stringify(filter);
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/query`;
return this.http
.post(url, data, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.listTasks(filter);
}
private callApiTaskFilters(appId?: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl();
if (appId) {
url = url + `/api/enterprise/filters/tasks?appId=${appId}`;
return this.authService.getAlfrescoApi().activiti.userFiltersApi.getUserTaskFilters({appId: appId});
} else {
url = url + `/api/enterprise/filters/tasks`;
return this.authService.getAlfrescoApi().activiti.userFiltersApi.getUserTaskFilters();
}
return this.http
.get(url, this.getRequestOptions()).toPromise();
}
private callApiTaskDetails(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}`;
return this.http
.get(url, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.getTask(id);
}
private callApiTaskComments(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/comments`;
return this.http
.get(url, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.getTaskComments(id);
}
private callApiAddTaskComment(id: string, message: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/comments`;
let body = JSON.stringify({message: message});
return this.http
.post(url, body, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.addTaskComment({message: message}, id);
}
private callApiAddTask(task: TaskDetailsModel) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${task.parentTaskId}/checklist`;
let body = JSON.stringify(task);
return this.http
.post(url, body, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.addSubtask(task.parentTaskId, task);
}
private callApiTaskChecklist(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/checklist`;
return this.http
.get(url, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.getChecklist(id);
}
private callApiCompleteTask(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/action/complete`;
return this.http
.put(url, this.getRequestOptions()).toPromise();
return this.authService.getAlfrescoApi().activiti.taskApi.completeTask(id);
}
/**
* The method write the error in the console browser
* @param error
* @returns {ErrorObservable}
*/
public handleError(error: Response): Observable<any> {
console.error('Error when logging in', error);
private handleError(error: any) {
console.error(error);
return Observable.throw(error || 'Server error');
}
private getHeaders(): Headers {
return new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': this.authService.getTicket('BPM')
});
}
private getRequestOptions(): RequestOptions {
let headers = this.getHeaders();
return new RequestOptions({headers: headers});
}
}
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -92,6 +92,69 @@ export class MyComponent implements OnInit {
- Translation Service
- Context Menu Service
#### Authentication Service
The authentication service is used inside the [login component](../ng2-alfresco-login) and is possible to find there an example of how to use it.
```javascript
import { Component } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';
import {
ALFRESCO_CORE_PROVIDERS,
AlfrescoSettingsService,
AlfrescoAuthenticationService
} from 'ng2-alfresco-core';
@Component({
selector: 'my-app',
template: `
<div *ngIf="!authenticated" >
Authentication failed to ip {{ ecmHost }} with user: admin, admin
</div>
<div *ngIf="authenticated">
Authentication successfull to ip {{ ecmHost }} with user: admin, admin, your token is {{ token }}
</div>`
})
class MyDemoApp {
authenticated: boolean = false;
ecmHost: string = 'http://127.0.0.1:8080';
token: string;
constructor(public alfrescoAuthenticationService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
alfrescoSettingsService.setProviders('ECM');
}
ngOnInit() {
this.login();
}
login() {
this.alfrescoAuthenticationService.login('admin', 'admin').subscribe(
token => {
this.token = token.ticket;
this.authenticated = true;
},
error => {
console.log(error);
this.authenticated = false;
});
}
}
bootstrap(MyDemoApp, [
HTTP_PROVIDERS,
ALFRESCO_CORE_PROVIDERS
]);
```
## Build from sources
Alternatively you can build component from sources with the following commands:
@@ -4,7 +4,7 @@ module.exports = function (config) {
var configuration = {
basePath: '.',
frameworks: ['jasmine'],
frameworks: ['jasmine-ajax', 'jasmine'],
files: [
// paths loaded by Karma
@@ -64,6 +64,7 @@ module.exports = function (config) {
plugins: [
'karma-jasmine',
'karma-coverage',
'karma-jasmine-ajax',
'karma-chrome-launcher',
'karma-mocha-reporter',
'karma-jasmine-html-reporter'
@@ -55,7 +55,7 @@
"alfresco"
],
"dependencies": {
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"@angular/common": "2.0.0-rc.3",
"@angular/compiler": "2.0.0-rc.3",
"@angular/core": "2.0.0-rc.3",
@@ -87,6 +87,7 @@
"karma-coverage": "1.0.0",
"karma-coveralls": "1.1.2",
"karma-jasmine": "1.0.2",
"karma-jasmine-ajax": "^0.1.13",
"karma-jasmine-html-reporter": "0.2.0",
"karma-mocha-reporter": "2.0.3",
"license-check": "1.1.5",
@@ -1,37 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { AlfrescoAuthenticationBPM } from '../services/AlfrescoAuthenticationBPM.service';
import { AlfrescoAuthenticationECM } from '../services/AlfrescoAuthenticationECM.service';
import { Http } from '@angular/http';
import { AlfrescoSettingsService } from '../services/AlfrescoSettingsService.service';
export class AuthenticationFactory {
public static createAuth(alfrescoSettingsService: AlfrescoSettingsService,
http: Http,
type: string): AbstractAuthentication {
if (type === 'ECM') {
return new AlfrescoAuthenticationECM(alfrescoSettingsService, http);
} else if (type === 'BPM') {
return new AlfrescoAuthenticationBPM(alfrescoSettingsService, http);
}
return null;
}
}
@@ -0,0 +1,327 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {it, describe, beforeEach, afterEach} from '@angular/core/testing';
import {ReflectiveInjector, provide} from '@angular/core';
import {AlfrescoSettingsService} from './AlfrescoSettings.service';
import {AlfrescoAuthenticationService} from './AlfrescoAuthentication.service';
declare var AlfrescoApi: any;
declare let jasmine: any;
describe('AlfrescoAuthentication', () => {
let injector, authService;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
provide(AlfrescoSettingsService, {useClass: AlfrescoSettingsService}),
AlfrescoAuthenticationService
]);
let store = {};
spyOn(localStorage, 'getItem').and.callFake(function (key) {
return store[key];
});
spyOn(localStorage, 'setItem').and.callFake(function (key, value) {
return store[key] = value + '';
});
spyOn(localStorage, 'clear').and.callFake(function () {
store = {};
});
spyOn(localStorage, 'removeItem').and.callFake(function (key) {
delete store[key];
});
spyOn(localStorage, 'key').and.callFake(function (i) {
let keys = Object.keys(store);
return keys[i] || null;
});
jasmine.Ajax.install();
});
afterEach(() => {
jasmine.Ajax.uninstall();
});
describe('when the setting is ECM', () => {
beforeEach(() => {
authService = injector.get(AlfrescoAuthenticationService);
authService.alfrescoSetting.setProviders('ECM');
});
it('should return an ECM ticket after the login done', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
expect(authService.isLoggedIn()).toBe(true);
expect(authService.getTicketEcm()).toEqual('fake-post-ticket');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 201,
contentType: 'application/json',
responseText: JSON.stringify({'entry': {'id': 'fake-post-ticket', 'userId': 'admin'}})
});
});
it('should return ticket undefined when the credentials are wrong', (done) => {
authService.login('fake-wrong-username', 'fake-wrong-password').subscribe(
(res) => {
},
(err: any) => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketEcm()).toBe(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 403,
contentType: 'application/json',
responseText: JSON.stringify({
'error': {
'errorKey': 'Login failed',
'statusCode': 403,
'briefSummary': '05150009 Login failed',
'stackTrace': 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.',
'descriptionURL': 'https://api-explorer.alfresco.com'
}
})
});
});
it('should login in the ECM if no provider are defined calling the login', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 201,
contentType: 'application/json',
responseText: JSON.stringify({'entry': {'id': 'fake-post-ticket', 'userId': 'admin'}})
});
});
it('should return a ticket undefined after logout', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
authService.logout().subscribe(() => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketEcm()).toBe(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 204
});
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 201,
contentType: 'application/json',
responseText: JSON.stringify({'entry': {'id': 'fake-post-ticket', 'userId': 'admin'}})
});
});
it('should return false if the user is not logged in', () => {
expect(authService.isLoggedIn()).toBe(false);
});
});
describe('when the setting is BPM', () => {
beforeEach(() => {
authService = injector.get(AlfrescoAuthenticationService);
authService.alfrescoSetting.setProviders('BPM');
});
it('should return an BPM ticket after the login done', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
expect(authService.isLoggedIn()).toBe(true);
expect(authService.getTicketBpm()).toEqual('Basic ZmFrZS11c2VybmFtZTpmYWtlLXBhc3N3b3Jk');
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200
});
});
it('should return ticket undefined when the credentials are wrong', (done) => {
authService.login('fake-wrong-username', 'fake-wrong-password').subscribe(
(res) => {
},
(err: any) => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 403
});
});
it('should return a ticket undefined after logout', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
authService.logout().subscribe(() => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200
});
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200
});
});
it('should return an error when the logout return error', (done) => {
authService.logout().subscribe(
(res) => {
},
(err: any) => {
expect(err).toBeDefined();
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 403
});
});
});
describe('Setting service change should reflect in the api', () => {
beforeEach(() => {
authService = injector.get(AlfrescoAuthenticationService);
authService.alfrescoSetting.setProviders('ALL');
});
it('should host ecm url change be reflected in the api configuration', () => {
authService.alfrescoSetting.ecmHost = '127.99.99.99';
expect(authService.getAlfrescoApi().config.hostEcm).toBe('127.99.99.99');
});
it('should host bpm url change be reflected in the api configuration', () => {
authService.alfrescoSetting.bpmHost = '127.99.99.99';
expect(authService.getAlfrescoApi().config.hostBpm).toBe('127.99.99.99');
});
it('should host bpm provider change be reflected in the api configuration', () => {
authService.alfrescoSetting.setProviders('ECM');
expect(authService.getAlfrescoApi().config.provider).toBe('ECM');
});
});
describe('when the setting is both ECM and BPM ', () => {
beforeEach(() => {
authService = injector.get(AlfrescoAuthenticationService);
authService.providers = 'ALL';
});
it('should return both ECM and BPM tickets after the login done', (done) => {
authService.login('fake-username', 'fake-password').subscribe(() => {
expect(authService.isLoggedIn()).toBe(true);
expect(authService.getTicketEcm()).toEqual('fake-post-ticket');
expect(authService.getTicketBpm()).toEqual('Basic ZmFrZS11c2VybmFtZTpmYWtlLXBhc3N3b3Jk');
done();
});
jasmine.Ajax.requests.at(0).respondWith({
'status': 201,
contentType: 'application/json',
responseText: JSON.stringify({'entry': {'id': 'fake-post-ticket', 'userId': 'admin'}})
});
jasmine.Ajax.requests.at(1).respondWith({
'status': 200
});
});
it('should return login fail if only ECM call fail', (done) => {
authService.login('fake-username', 'fake-password').subscribe(
(res) => {
},
(err: any) => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketEcm()).toBe(null);
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.at(0).respondWith({
'status': 403
});
jasmine.Ajax.requests.at(1).respondWith({
'status': 200
});
});
it('should return login fail if only BPM call fail', (done) => {
authService.login('fake-username', 'fake-password').subscribe(
(res) => {
},
(err: any) => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketEcm()).toBe(null);
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.at(0).respondWith({
'status': 201,
contentType: 'application/json',
responseText: JSON.stringify({'entry': {'id': 'fake-post-ticket', 'userId': 'admin'}})
});
jasmine.Ajax.requests.at(1).respondWith({
'status': 403
});
});
it('should return ticket undefined when the credentials are wrong', (done) => {
authService.login('fake-username', 'fake-password').subscribe(
(res) => {
},
(err: any) => {
expect(authService.isLoggedIn()).toBe(false);
expect(authService.getTicketEcm()).toBe(null);
expect(authService.getTicketBpm()).toBe(null);
done();
});
jasmine.Ajax.requests.at(0).respondWith({
'status': 403
});
jasmine.Ajax.requests.at(1).respondWith({
'status': 403
});
});
});
});
@@ -0,0 +1,195 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Rx';
import {AlfrescoSettingsService} from './AlfrescoSettings.service';
declare let AlfrescoApi: any;
/**
* The AlfrescoAuthenticationService provide the login service and store the ticket in the localStorage
*/
@Injectable()
export class AlfrescoAuthenticationService {
alfrescoApi: any;
/**A
* Constructor
* @param alfrescoSetting
*/
constructor(public alfrescoSetting: AlfrescoSettingsService) {
this.alfrescoApi = new AlfrescoApi({
provider: this.alfrescoSetting.getProviders(),
ticketEcm: this.getTicketEcm(),
ticketBpm: this.getTicketBpm(),
hostEcm: this.alfrescoSetting.ecmHost,
hostBpm: this.alfrescoSetting.bpmHost
});
alfrescoSetting.bpmHostSubject.subscribe((bpmHost) => {
this.alfrescoApi.changeBpmHost(bpmHost);
});
alfrescoSetting.ecmHostSubject.subscribe((ecmHost) => {
this.alfrescoApi.changeEcmHost(ecmHost);
});
alfrescoSetting.providerSubject.subscribe((value) => {
this.alfrescoApi.config.provider = value;
});
}
/**
* The method return tru if the user is logged in
* @returns {boolean}
*/
isLoggedIn(): boolean {
return !!this.alfrescoApi.isLoggedIn();
}
/**
* Method to delegate to POST login
* @param username
* @param password
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string) {
return Observable.fromPromise(this.callApiLogin(username, password))
.map((response: any) => {
this.saveTickets();
return {type: this.alfrescoSetting.getProviders(), ticket: response};
})
.catch(this.handleError);
}
/**
* Initialize the alfresco Api with user and password end call the login method
* @param username
* @param password
* @returns {*|Observable<any>}
*/
private callApiLogin(username: string, password: string) {
return this.alfrescoApi.login(username, password);
}
/**
* The method remove the ticket from the local storage
*
* @returns {Observable<R>|Observable<T>}
*/
public logout() {
return Observable.fromPromise(this.callApiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket();
return response;
})
.catch(this.handleError);
}
/**
*
* @returns {*|Observable<string>|Observable<any>|Promise<T>}
*/
private callApiLogout(): Promise<any> {
if (this.alfrescoApi) {
return this.alfrescoApi.logout();
}
}
/**
* Remove the login ticket from localStorage
*/
public removeTicket(): void {
localStorage.removeItem('ticket-ECM');
localStorage.removeItem('ticket-BPM');
}
/**
* The method return the ECM ticket stored in the localStorage
* @returns ticket
*/
public getTicketEcm(): string {
if (localStorage.getItem('ticket-ECM')) {
return localStorage.getItem('ticket-ECM');
} else {
return null;
}
}
/**
* The method return the BPM ticket stored in the localStorage
* @returns ticket
*/
public getTicketBpm(): string {
if (localStorage.getItem('ticket-BPM')) {
return localStorage.getItem('ticket-BPM');
} else {
return null;
}
}
public getTicketEcmBase64(): string {
if (localStorage.getItem('ticket-ECM')) {
return 'Basic ' + btoa(localStorage.getItem('ticket-ECM'));
} else {
return null;
}
}
/**
* The method save the ECM and BPM ticket in the localStorage
*/
public saveTickets() {
this.saveTicketEcm();
this.saveTicketBpm();
}
/**
* The method save the ECM ticket in the localStorage
*/
public saveTicketEcm(): void {
if (this.alfrescoApi) {
localStorage.setItem('ticket-ECM', this.alfrescoApi.getTicketEcm());
}
}
/**
* The method save the BPM ticket in the localStorage
*/
public saveTicketBpm(): void {
if (this.alfrescoApi) {
localStorage.setItem('ticket-BPM', this.alfrescoApi.getTicketBpm());
}
}
/**
* The method write the error in the console browser
* @param error
* @returns {ErrorObservable}
*/
public handleError(error: any): Observable<any> {
console.error('Error when logging in', error);
return Observable.throw(error || 'Server error');
}
getAlfrescoApi(): any {
return this.alfrescoApi;
}
}
@@ -1,116 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
export class AlfrescoAuthenticationBPM extends AlfrescoAuthenticationBase implements AbstractAuthentication {
TYPE: string = 'BPM';
constructor(alfrescoSetting: AlfrescoSettingsService,
http: Http) {
super(alfrescoSetting, http);
}
getHost(): string {
return this.alfrescoSetting.bpmHost;
}
/**
* Perform a login on behalf of the user and store the ticket returned
*
* @param username
* @param password
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string): Observable<any> {
return Observable.fromPromise(this.apiActivitiLogin(username, password))
.map((response: any) => {
return {
type: this.TYPE,
ticket: 'Basic ' + btoa(`${username}:${password}`)
};
})
.catch(this.handleError);
}
/**
* Delete the current login ticket from the server
*
* @returns {Observable<R>|Observable<T>}
*/
logout() {
return Observable.fromPromise(this.apiActivitiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket(this.TYPE);
})
.catch(this.handleError);
}
/**
* The method return true if the user is logged in
* @returns {boolean}
*/
isLoggedIn(): boolean {
return !!this.getTicket();
}
private apiActivitiLogin(username: string, password: string) {
let url = this.alfrescoSetting.getBPMApiBaseUrl() + '/app/authentication';
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
});
let options = new RequestOptions({headers: headers});
let data = 'j_username='
+ encodeURIComponent(username)
+ '&j_password='
+ encodeURIComponent(password)
+ '&_spring_security_remember_me=true&submit=Login';
return this.http
.post(url, data, options).toPromise();
}
private apiActivitiLogout() {
let url = this.alfrescoSetting.getBPMApiBaseUrl() + '/app/logout';
return this.http.get(url).toPromise();
}
/**
* The method return the ticket stored in the localStorage
* @returns ticket
*/
public getTicket(): string {
return localStorage.getItem(`ticket-${this.TYPE}`);
}
/**
* The method save the ticket in the localStorage
* @param ticket
*/
public saveTicket(ticket: string): void {
if (ticket) {
super.saveTicket(this.TYPE, ticket);
}
}
}
@@ -1,64 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Http, Response } from '@angular/http';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { Observable } from 'rxjs/Rx';
declare let AlfrescoApi: any;
export class AlfrescoAuthenticationBase {
alfrescoApi: any;
/**
* Constructor
* @param alfrescoSettingsService
*/
constructor(public alfrescoSetting: AlfrescoSettingsService,
public http: Http) {
}
/**
* The method save the toke in the localStorage
* @param ticket
*/
public saveTicket(provider: string, ticket: string): void {
if (ticket) {
localStorage.setItem(`ticket-${provider}`, ticket);
}
}
/**
* Remove the login ticket from localStorage
*/
public removeTicket(provider: string): void {
localStorage.removeItem(`ticket-${provider}`);
}
/**
* The method write the error in the console browser
* @param error
* @returns {ErrorObservable}
*/
public handleError(error: Response): Observable<any> {
console.error('Error when logging in', error);
return Observable.throw(error || 'Server error');
}
}
@@ -1,137 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { Observable } from 'rxjs/Rx';
import { Http } from '@angular/http';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
declare let AlfrescoApi: any;
export class AlfrescoAuthenticationECM extends AlfrescoAuthenticationBase implements AbstractAuthentication {
TYPE: string = 'ECM';
alfrescoApi: any;
/**
* Constructor
* @param alfrescoSetting
* @param http
*/
constructor(alfrescoSetting: AlfrescoSettingsService,
http: Http) {
super(alfrescoSetting, http);
if (!this.isLoggedIn()) {
this.alfrescoApi = new AlfrescoApi({
host: this.getHost()
});
} else {
this.alfrescoApi = new AlfrescoApi({
ticket: this.getTicket(),
host: this.getHost()
});
}
}
getHost(): string {
return this.alfrescoSetting.ecmHost;
}
/**
* The method return tru if the user is logged in
* @returns {boolean}
*/
isLoggedIn(): boolean {
return !!this.getTicket();
}
/**
* Method to delegate to POST login
* @param username
* @param password
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string) {
return Observable.fromPromise(this.callApiLogin(username, password))
.map((response: any) => {
return {type: this.TYPE, ticket: response};
})
.catch(this.handleError);
}
/**
* Initialize the alfresco Api with user and password end call the login method
* @param username
* @param password
* @returns {*|Observable<any>}
*/
private callApiLogin(username: string, password: string) {
this.alfrescoApi = new AlfrescoApi({
username: username,
password: password,
host: this.getHost()
});
return this.alfrescoApi.login();
}
/**
* The method remove the ticket from the local storage
*
* @returns {Observable<R>|Observable<T>}
*/
public logout() {
return Observable.fromPromise(this.callApiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket(this.TYPE);
return response;
})
.catch(this.handleError);
}
/**
*
* @returns {*|Observable<string>|Observable<any>|Promise<T>}
*/
private callApiLogout(): Promise<any> {
return this.alfrescoApi.logout();
}
/**
* The method return the ticket stored in the localStorage
* @returns ticket
*/
public getTicket(): string {
return localStorage.getItem(`ticket-${this.TYPE}`);
}
/**
* The method save the ticket in the localStorage
* @param ticket
*/
public saveTicket(ticket): void {
if (ticket) {
super.saveTicket(this.TYPE, ticket);
}
}
}
@@ -1,460 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { it, describe } from '@angular/core/testing';
import { ReflectiveInjector, provide } from '@angular/core';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoAuthenticationECM } from './AlfrescoAuthenticationECM.service';
import { AlfrescoAuthenticationBPM } from './AlfrescoAuthenticationBPM.service';
import { XHRBackend, HTTP_PROVIDERS } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
declare var AlfrescoApi: any;
describe('AlfrescoAuthentication', () => {
let injector,
fakePromiseECM,
fakePromiseBPM,
service;
fakePromiseECM = new Promise(function (resolve, reject) {
resolve(
'fake-post-ticket-ECM'
);
reject({
response: {
error: 'fake-error'
}
});
});
fakePromiseBPM = new Promise(function (resolve, reject) {
resolve({
status: 'fake-post-ticket-BPM'
});
reject({
response: {
error: 'fake-error'
}
});
});
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
HTTP_PROVIDERS,
provide(XHRBackend, {useClass: MockBackend}),
provide(AlfrescoSettingsService, {useClass: AlfrescoSettingsService}),
AlfrescoAuthenticationService
]);
let store = {};
spyOn(localStorage, 'getItem').and.callFake(function (key) {
return store[key];
});
spyOn(localStorage, 'setItem').and.callFake(function (key, value) {
return store[key] = value + '';
});
spyOn(localStorage, 'clear').and.callFake(function () {
store = {};
});
spyOn(localStorage, 'removeItem').and.callFake(function (key) {
delete store[key];
});
spyOn(localStorage, 'key').and.callFake(function (i) {
let keys = Object.keys(store);
return keys[i] || null;
});
// service = injector.get(AlfrescoAuthenticationService);
});
describe('when the setting is ECM', () => {
it('should create an AlfrescoAuthenticationECM instance', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(1);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
done();
}
);
});
it('should return an ECM ticket after the login done', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.getTicket(providers[0])).toEqual('fake-post-ticket-ECM');
done();
}
);
});
it('should return ticket undefined when the credentials are wrong', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin')
.and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-wrong-username', 'fake-wrong-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
done();
}
);
});
it('should return an error if no provider are defined calling the login', (done) => {
let providers = [];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err).toEqual('No providers defined');
done();
}
);
});
it('should return an error if an empty provider are defined calling the login', (done) => {
let providers = [''];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err.message).toEqual('Wrong provider defined');
done();
}
);
});
it('should return a ticket undefined after logout', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-ECM', 'fake-post-ticket-ECM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
}
);
});
it('should logout only for if the provider is loggedin', (done) => {
let providers = ['BPM', 'ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-ECM', 'fake-post-ticket-ECM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
service.performeSaveTicket('ECM', 'fake-ticket-ECM');
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
}
);
});
it('should return an error if no provider are defined calling the logout', (done) => {
let providers = [];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
service.logout()
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err).toEqual('No providers defined');
done();
}
);
});
it('should return false if the user is not logged in', () => {
let providers = ['ECM'];
expect(service.isLoggedIn(providers[0])).toBe(false);
});
});
describe('when the setting is BPM', () => {
it('should create an AlfrescoAuthenticationBPM instance', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(1);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
done();
}
);
});
it('should return an BPM ticket after the login done', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
let username = 'fake-username';
let password = 'fake-password';
let token = 'Basic ' + btoa(`${username}:${password}`);
service.login(username, password, providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.getTicket(providers[0])).toEqual(token);
done();
}
);
});
it('should return ticket undefined when the credentials are wrong', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-wrong-username', 'fake-wrong-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
done();
}
);
});
it('should return a ticket undefined after logout', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-BPM', 'fake-post-ticket-BPM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogout').and.returnValue(fakePromiseBPM);
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(localStorage.getItem('ticket-BPM')).toBeUndefined();
done();
}
);
});
it('should throw an error when the logout return error', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-BPM', 'fake-post-ticket-BPM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogout').and.returnValue(Promise.reject('fake logout error'));
service.logout()
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err.message).toEqual('fake logout error');
expect(localStorage.getItem('ticket-BPM')).toEqual('fake-post-ticket-BPM');
done();
}
);
});
});
describe('when the setting is both ECM and BPM ', () => {
it('should create both instances', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.isLoggedIn(providers[1])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(2);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
expect(service.providersInstance[1].TYPE).toEqual(providers[1]);
done();
}
);
});
it('should return both ECM and BPM tickets after the login done', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
let username = 'fake-username';
let password = 'fake-password';
let bpmToken = 'Basic ' + btoa(`${username}:${password}`);
service.login(username, password, providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.isLoggedIn(providers[1])).toBe(true);
expect(service.getTicket(providers[0])).toEqual('fake-post-ticket-ECM');
expect(service.getTicket(providers[1])).toEqual(bpmToken);
done();
}
);
});
it('should return ticket undefined when the credentials are correct for the ECM login but wrong for the BPM login', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn(providers[1])).toBe(false);
expect(service.getTicket(providers[1])).toBeUndefined();
done();
}
);
});
it('should return ticket undefined when the credentials are correct for the BPM login but wrong for the ECM login', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin')
.and.returnValue(Promise.reject('fake invalid credentials'));
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn(providers[1])).toBe(false);
expect(service.getTicket(providers[1])).toBeUndefined();
done();
}
);
});
});
});
@@ -1,205 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Http } from '@angular/http';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AuthenticationFactory } from '../factory/AuthenticationFactory';
import { AbstractAuthentication } from '../interface/authentication.interface';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
declare let AlfrescoApi: any;
/**
* The AlfrescoAuthenticationService provide the login service and store the ticket in the localStorage
*/
@Injectable()
export class AlfrescoAuthenticationService extends AlfrescoAuthenticationBase {
private providersInstance: AbstractAuthentication[] = [];
/**
* Constructor
* @param settingsService
* @param http
*/
constructor(settingsService: AlfrescoSettingsService,
http: Http) {
super(settingsService, http);
if (settingsService) {
this.createProviderInstance(settingsService.getProviders());
}
}
/**
* Method to delegate to POST login
* @param username
* @param password
* @param providers
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string, providers: string []): Observable<string> {
localStorage.clear();
if (providers.length === 0) {
return Observable.throw('No providers defined');
} else {
return this.performeLogin(username, password, providers);
}
}
/**
* Perform a login on behalf of the user for the different provider instance
*
* @param username
* @param password
* @param providers
* @returns {Observable<R>|Observable<T>}
*/
private performeLogin(username: string, password: string, providers: string []): Observable<any> {
let observableBatch = [];
providers.forEach((provider) => {
let auth: AbstractAuthentication = this.findProviderInstance(provider);
if (auth) {
observableBatch.push(auth.login(username, password));
} else {
observableBatch.push(Observable.throw('Wrong provider defined'));
}
});
return Observable.create(observer => {
Observable.forkJoin(observableBatch).subscribe(
(response: any[]) => {
response.forEach((res) => {
this.performeSaveTicket(res.type, res.ticket);
});
observer.next(response);
},
(err: any) => {
observer.error(new Error(err));
});
});
}
/**
* The method return true if the user is logged in
* @returns {boolean}
*/
isLoggedIn(type: string = 'ECM'): boolean {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
return auth.isLoggedIn();
}
return false;
}
getAlfrescoApi(): any {
return this.findProviderInstance('ECM').alfrescoApi;
}
/**
* Return the ticket stored in the localStorage of the specific provider type
* @param type
*/
public getTicket(type: string = 'ECM'): string {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
return auth.getTicket();
}
return '';
}
/**
* Save the token calling the method of the specific provider type
* @param type - providerName
* @param ticket
*/
private performeSaveTicket(type: string, ticket: string) {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
auth.saveTicket(ticket);
}
}
/**
* The method remove the ticket from the local storage
* @returns {Observable<T>}
*/
public logout(): Observable<string> {
if (this.providersInstance.length === 0) {
return Observable.throw('No providers defined');
} else {
return this.performLogout();
}
}
/**
* Perform a logout on behalf of the user for the different provider instance
*
* @returns {Observable<R>|Observable<T>}
*/
private performLogout(): Observable<any> {
let observableBatch = [];
this.providersInstance.forEach((authInstance) => {
if (authInstance.isLoggedIn()) {
observableBatch.push(authInstance.logout());
}
});
return Observable.create(observer => {
Observable.forkJoin(observableBatch).subscribe(
(response: any[]) => {
observer.next(response);
},
(err: any) => {
observer.error(new Error(err));
});
});
}
/**
* Create the provider instance using a Factory
* @param providers - list of the providers like ECM BPM
*/
public createProviderInstance(providers: string []): void {
if (this.providersInstance.length === 0) {
providers.forEach((provider) => {
let authInstance: AbstractAuthentication = AuthenticationFactory.createAuth(
this.alfrescoSetting, this.http, provider);
if (authInstance) {
this.providersInstance.push(authInstance);
}
});
}
}
/**
* Find the provider by type and return it
* @param type
* @returns {AbstractAuthentication}
*/
private findProviderInstance(type: string): AbstractAuthentication {
let auth: AbstractAuthentication = null;
if (this.providersInstance && this.providersInstance.length !== 0) {
this.providersInstance.forEach((provider) => {
if (provider.TYPE === type.toUpperCase()) {
auth = provider;
}
});
}
return auth;
}
}
@@ -17,7 +17,7 @@
import { Injectable } from '@angular/core';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoAuthenticationService } from './AlfrescoAuthentication.service';
@Injectable()
export class AlfrescoContentService {
@@ -0,0 +1,61 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, it, beforeEach} from '@angular/core/testing';
import {ReflectiveInjector} from '@angular/core';
import {AlfrescoSettingsService} from './AlfrescoSettings.service';
import {AlfrescoAuthenticationService} from './AlfrescoAuthentication.service';
import {AlfrescoContentService} from './AlfrescoContent.service';
describe('AlfrescoContentService', () => {
let injector, contentService: AlfrescoContentService, authService: AlfrescoAuthenticationService, node;
const nodeId = 'fake-node-id';
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
AlfrescoContentService,
AlfrescoAuthenticationService,
AlfrescoSettingsService
]);
spyOn(localStorage, 'getItem').and.callFake(function (key) {
return 'myTicket';
});
contentService = injector.get(AlfrescoContentService);
authService = injector.get(AlfrescoAuthenticationService);
authService.login('fake-username', 'fake-password');
node = {
entry: {
id: nodeId
}
};
});
it('should return a valid content URL', () => {
expect(contentService.getContentUrl(node)).toBe('http://localhost:8080/alfresco/api/' +
'-default-/public/alfresco/versions/1/nodes/fake-node-id/content?attachment=false&alf_ticket=myTicket');
});
it('should return a valid thumbnail URL', () => {
expect(contentService.getDocumentThumbnailUrl(node))
.toBe('http://localhost:8080/alfresco/api/-default-/public/alfresco' +
'/versions/1/nodes/fake-node-id/renditions/doclib/content?attachment=false&alf_ticket=myTicket');
});
});
@@ -1,69 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { describe, it, beforeEach } from '@angular/core/testing';
import { ReflectiveInjector } from '@angular/core';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoContentService } from './AlfrescoContentService.service';
import { HTTP_PROVIDERS } from '@angular/http';
describe('AlfrescoContentService', () => {
let injector, service: AlfrescoContentService, authService: AlfrescoAuthenticationService;
const nodeId = 'blah';
let DEFAULT_CONTEXT_PATH: string = '/alfresco';
let DEFAULT_BASE_API_PATH: string = '/api/-default-/public/alfresco/versions/1';
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
HTTP_PROVIDERS,
AlfrescoContentService,
AlfrescoAuthenticationService,
AlfrescoSettingsService
]);
spyOn(localStorage, 'getItem').and.callFake(function (key) {
return 'myTicket';
});
service = injector.get(AlfrescoContentService);
authService = injector.get(AlfrescoAuthenticationService);
});
it('should return a valid content URL', () => {
expect(service.getContentUrl({
entry: {
id: nodeId
}
})).toBe(
AlfrescoSettingsService.DEFAULT_ECM_ADDRESS + DEFAULT_CONTEXT_PATH +
DEFAULT_BASE_API_PATH + '/nodes/' + nodeId + '/content' +
'?attachment=false&alf_ticket=' + authService.getTicket()
);
});
it('should return a valid thumbnail URL', () => {
expect(service.getDocumentThumbnailUrl({
entry: {
id: nodeId
}
})).toBe(
AlfrescoSettingsService.DEFAULT_ECM_ADDRESS + DEFAULT_CONTEXT_PATH +
DEFAULT_BASE_API_PATH + '/nodes/' + nodeId + '/renditions/doclib/content' +
'?attachment=false&alf_ticket=' + authService.getTicket()
);
});
});
@@ -17,7 +17,7 @@
import { Injectable, ChangeDetectorRef, Pipe } from '@angular/core';
import { TranslatePipe } from 'ng2-translate/ng2-translate';
import { AlfrescoTranslationService } from './AlfrescoTranslationService.service';
import { AlfrescoTranslationService } from './AlfrescoTranslation.service';
@Injectable()
@Pipe({
@@ -16,6 +16,7 @@
*/
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class AlfrescoSettingsService {
@@ -23,50 +24,47 @@ export class AlfrescoSettingsService {
static DEFAULT_ECM_ADDRESS: string = 'http://' + window.location.hostname + ':8080';
static DEFAULT_BPM_ADDRESS: string = 'http://' + window.location.hostname + ':9999';
static DEFAULT_ECM_CONTEXT_PATH: string = '/alfresco';
static DEFAULT_BPM_CONTEXT_PATH: string = '/activiti-app';
static DEFAULT_ECM_BASE_API_PATH: string = '/api/-default-/public/alfresco/versions/1';
private _ecmHost: string = AlfrescoSettingsService.DEFAULT_ECM_ADDRESS;
private _bpmHost: string = AlfrescoSettingsService.DEFAULT_BPM_ADDRESS;
private _ecmContextPath = AlfrescoSettingsService.DEFAULT_ECM_CONTEXT_PATH;
private _bpmContextPath = AlfrescoSettingsService.DEFAULT_BPM_CONTEXT_PATH;
private _apiECMBasePath: string = AlfrescoSettingsService.DEFAULT_ECM_BASE_API_PATH;
private providers: string = 'ALL'; // ECM, BPM , ALL
private providers: string[] = ['ECM', 'BPM'];
bpmHostSubject: Subject<string> = new Subject<string>();
ecmHostSubject: Subject<string> = new Subject<string>();
providerSubject: Subject<string> = new Subject<string>();
public get ecmHost(): string {
return this._ecmHost;
}
public set ecmHost(value: string) {
this._ecmHost = value;
public set ecmHost(ecmHostUrl: string) {
this.ecmHostSubject.next(ecmHostUrl);
this._ecmHost = ecmHostUrl;
}
public get bpmHost(): string {
return this._bpmHost;
}
public set bpmHost(value: string) {
this._bpmHost = value;
public set bpmHost(bpmHostUrl: string) {
this.bpmHostSubject.next(bpmHostUrl);
this._bpmHost = bpmHostUrl;
}
public getBPMApiBaseUrl(): string {
return this._bpmHost + this._bpmContextPath;
}
public getECMApiBaseUrl(): string {
return this._ecmHost + this._ecmContextPath + this._apiECMBasePath;
}
public getProviders(): string [] {
public getProviders(): string {
return this.providers;
}
public setProviders(providers: string []) {
public setProviders(providers: string) {
this.providerSubject.next(providers);
this.providers = providers;
}
}
@@ -16,7 +16,7 @@
*/
import { describe, it, beforeEach } from '@angular/core/testing';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AlfrescoSettingsService } from './AlfrescoSettings.service';
describe('AlfrescoSettingsService', () => {
@@ -15,9 +15,9 @@
* limitations under the License.
*/
export * from './AlfrescoSettingsService.service';
export * from './AlfrescoSettings.service';
export * from './AlfrescoTranslationLoader.service';
export * from './AlfrescoTranslationService.service';
export * from './AlfrescoTranslation.service';
export * from './AlfrescoPipeTranslate.service';
export * from './AlfrescoAuthenticationService.service';
export * from './AlfrescoContentService.service';
export * from './AlfrescoAuthentication.service';
export * from './AlfrescoContent.service';
+1 -1
View File
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
+119 -119
View File
@@ -1,121 +1,121 @@
{
"rules": {
"align": [
true,
"parameters",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"label-undefined": true,
"max-line-length": [
true,
140
],
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": false,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-constructor-vars": false,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-require-imports": true,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": true,
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-strict": false,
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-type",
"check-module",
"check-decl"
]
}
"rules": {
"align": [
true,
"parameters",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"label-undefined": true,
"max-line-length": [
true,
180
],
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": false,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-constructor-vars": false,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-require-imports": true,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": true,
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-strict": false,
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-type",
"check-module",
"check-decl"
]
}
}
@@ -36,7 +36,7 @@
"material-design-icons": "2.2.3",
"material-design-lite": "1.1.3",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "^0.2.0",
"ng2-alfresco-documentlist": "^0.2.0",
"ng2-alfresco-datatable": "^0.2.0"
@@ -144,17 +144,16 @@ class DocumentListDemo implements OnInit {
authenticated: boolean;
ecmHost: string = 'http://devproducts-platform.alfresco.me';
// ecmHost: string = 'http://127.0.0.1:8080';
token: string;
constructor(
private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService,
private settingsService: AlfrescoSettingsService,
translation: AlfrescoTranslationService,
private documentActions: DocumentActionsService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
settingsService.ecmHost = this.ecmHost;
if (this.authService.getTicket()) {
this.token = this.authService.getTicket();
}
@@ -167,7 +166,7 @@ class DocumentListDemo implements OnInit {
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
@@ -190,7 +189,7 @@ class DocumentListDemo implements OnInit {
}
login() {
this.authService.login('admin', 'admin', ['ECM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -72,7 +72,7 @@
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"alfresco-js-api": "0.2.0"
"alfresco-js-api": "^0.3.0"
},
"peerDependencies": {
"material-design-icons": "^2.2.3",
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
+10 -11
View File
@@ -83,7 +83,7 @@ Also make sure you include these dependencies in your .html page:
## Basic usage
```html
<alfresco-login [providers]="['ECM','BPM']"></alfresco-login>
<alfresco-login [providers]="'ALL'"></alfresco-login>
```
Example of an App that use Alfresco login component :
@@ -105,7 +105,7 @@ import {
selector: 'my-app',
template: '
<alfresco-login
providers=['ECM']
providers="'ALL'"
(onSuccess)="mySuccessMethod($event)"
(onError)="myErrorMethod($event)">
</alfresco-login>',
@@ -141,18 +141,17 @@ bootstrap(AppComponent, [
| onSuccess | The event is emitted when the login is done |
| onError | The event is emitted when the login fails |
Attribute | Description |
--- | --- |
`onSuccess` | The event is emitted when the login is done |
`onError` | The event is emitted when the login fails |
#### Options
**providers**: { string[] } optional) default ECM.
Attribute | Options | Default | Description | Mandatory
--- | --- | --- | --- | ---
`providers` | *string* | ECM | Possible valid value are ECM, BPM or ALL. The default behaviour of this component will logged in only in the ECM . If you want log in in both system the correct value to use is ALL |
Using the providers attribute, you can specify in which system
(ECM or BPM) you want to be logged in.
By selecting one of the options only the relative components will be
accesible. For instance if you activate the ECM login then only the
ECM component will be visible,same behaviour for BPM selection.
You can also specify ECM and BPM, in this case both system components
are accessible.<br />
## Custom logo and background
@@ -66,7 +66,7 @@
"material-design-lite": "1.1.3",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "^0.1.36",
"ng2-alfresco-login": "file:../"
},
@@ -62,15 +62,15 @@ export class AppComponent {
public status: string = '';
public providers: string [] = ['ECM'];
public providers: string = 'ECM';
constructor(public auth: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
private settingsService: AlfrescoSettingsService) {
settingsService.ecmHost = this.ecmHost;
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
}
mySuccessMethod($event) {
@@ -84,18 +84,22 @@ export class AppComponent {
}
toggleECM(checked) {
if (checked) {
this.providers[0] = 'ECM';
if (checked && this.providers === 'BPM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'ECM';
} else {
this.providers[0] = '';
this.providers = undefined;
}
}
toggleBPM(checked) {
if (checked) {
this.providers[1] = 'BPM';
if (checked && this.providers === 'ECM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'BPM';
} else {
this.providers[1] = '';
this.providers = undefined;
}
}
}
@@ -75,7 +75,7 @@
"zone.js": "0.6.12",
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "0.2.0",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"coveralls": "^2.11.9"
},
"devDependencies": {
@@ -23,7 +23,7 @@ import {
beforeEach,
beforeEachProviders
} from '@angular/core/testing';
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
import { TestComponentBuilder } from '@angular/compiler/testing';
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { AlfrescoLoginComponent } from './alfresco-login.component';
@@ -38,6 +38,7 @@ describe('AlfrescoLogin', () => {
beforeEachProviders(() => {
return [
{ provide: AlfrescoAuthenticationService, useClass: AuthenticationMock },
AlfrescoSettingsService,
{ provide: AlfrescoTranslationService, useClass: TranslationMock }
];
});
@@ -15,12 +15,13 @@
* limitations under the License.
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { FORM_DIRECTIVES, ControlGroup, FormBuilder, Validators } from '@angular/common';
import {Component, Input, Output, EventEmitter} from '@angular/core';
import {FORM_DIRECTIVES, ControlGroup, FormBuilder, Validators} from '@angular/common';
import {
AlfrescoTranslationService,
AlfrescoPipeTranslate,
AlfrescoAuthenticationService
AlfrescoAuthenticationService,
AlfrescoSettingsService
} from 'ng2-alfresco-core';
declare let componentHandler: any;
@@ -48,7 +49,7 @@ export class AlfrescoLoginComponent {
backgroundImageUrl: string;
@Input()
providers: string [] ;
providers: string ;
@Output()
onSuccess = new EventEmitter();
@@ -67,11 +68,13 @@ export class AlfrescoLoginComponent {
/**
* Constructor
* @param _fb
* @param auth
* @param authService
* @param settingsService
* @param translate
*/
constructor(private _fb: FormBuilder,
public auth: AlfrescoAuthenticationService,
public authService: AlfrescoAuthenticationService,
public settingsService: AlfrescoSettingsService,
private translate: AlfrescoTranslationService) {
this.formError = {
@@ -79,7 +82,7 @@ export class AlfrescoLoginComponent {
'password': ''
};
this.form = this._fb.group({
this.form = this._fb.group({
username: ['', Validators.compose([Validators.required, Validators.minLength(4)])],
password: ['', Validators.required]
});
@@ -104,12 +107,15 @@ export class AlfrescoLoginComponent {
* @param value
* @param event
*/
onSubmit(value: any, event) {
onSubmit(value: any, event: any) {
this.error = false;
if (event) {
event.preventDefault();
}
this.auth.login(value.username, value.password, this.providers)
this.settingsService.setProviders(this.providers);
this.authService.login(value.username, value.password)
.subscribe(
(token: any) => {
this.success = true;
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -66,7 +66,7 @@
"material-design-icons": "2.2.3",
"material-design-lite": "1.1.3",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "^0.1.36",
"ng2-alfresco-search": "^0.1.25"
},
@@ -63,16 +63,16 @@ class SearchDemo implements OnInit {
token: string;
constructor(private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService,
private settingsService: AlfrescoSettingsService,
translation: AlfrescoTranslationService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
settingsService.ecmHost = this.ecmHost;
translation.addTranslationFolder();
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
@@ -81,7 +81,7 @@ class SearchDemo implements OnInit {
}
login() {
this.authService.login('admin', 'admin', ['ECM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -71,7 +71,7 @@
"zone.js": "0.6.12",
"ng2-translate": "2.2.2",
"material-design-lite": "1.1.3",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "0.2.0"
},
"peerDependencies": {
@@ -1,41 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Observable} from 'rxjs/Rx';
import {
AlfrescoAuthenticationService
} from 'ng2-alfresco-core';
import {AlfrescoSearchService} from './../../src/services/alfresco-search.service';
export class AlfrescoServiceMock extends AlfrescoSearchService {
_folderToReturn: any = {};
constructor(
authService: AlfrescoAuthenticationService = null
) {
super(authService);
}
getFolder(folder: string) {
return Observable.create(observer => {
observer.next(this._folderToReturn);
observer.complete();
});
}
}
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -66,7 +66,7 @@
"material-design-icons": "2.2.3",
"material-design-lite": "1.1.3",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "^0.1.36",
"ng2-alfresco-upload": "^0.1.49"
},
@@ -80,8 +80,8 @@ export class MyDemoApp implements OnInit {
token: string;
constructor(private authService: AlfrescoAuthenticationService, private alfrescoSettingsService: AlfrescoSettingsService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) {
settingsService.ecmHost = this.ecmHost;
if (this.authService.getTicket()) {
this.token = this.authService.getTicket();
@@ -93,7 +93,7 @@ export class MyDemoApp implements OnInit {
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
@@ -106,7 +106,7 @@ export class MyDemoApp implements OnInit {
}
login() {
this.authService.login('admin', 'admin', ['ECM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -71,7 +71,7 @@
"rxjs": "5.0.0-beta.6",
"zone.js": "0.6.12",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-core": "0.2.0"
},
"peerDependencies": {
@@ -1,36 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
@Injectable()
export class AlfrescoSettingsServiceMock {
static DEFAULT_HOST_ADDRESS: string = 'fakehost';
private providers: string[] = ['ECM', 'BPM'];
private _host: string = AlfrescoSettingsServiceMock.DEFAULT_HOST_ADDRESS;
public get ecmHost(): string {
return this._host;
}
getProviders(): string [] {
return this.providers;
}
}
@@ -21,8 +21,8 @@ import { UploadButtonComponent } from './upload-button.component';
import { AlfrescoTranslationService, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { TranslationMock } from '../assets/translation.service.mock';
import { UploadService } from '../services/upload.service';
import { AlfrescoSettingsServiceMock } from '../assets/AlfrescoSettingsService.service.mock';
import { HTTP_PROVIDERS } from '@angular/http';
declare var AlfrescoApi: any;
describe('AlfrescoUploadButton', () => {
@@ -69,7 +69,7 @@ describe('AlfrescoUploadButton', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{ provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock },
AlfrescoSettingsService,
AlfrescoAuthenticationService,
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
UploadService
@@ -19,7 +19,6 @@ import { describe, expect, it, inject, beforeEach, beforeEachProviders } from '@
import { TestComponentBuilder } from '@angular/compiler/testing';
import { UploadDragAreaComponent } from './upload-drag-area.component';
import { AlfrescoTranslationService, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { AlfrescoSettingsServiceMock } from '../assets/AlfrescoSettingsService.service.mock';
import { TranslationMock } from '../assets/translation.service.mock';
import { UploadService } from '../services/upload.service';
import { HTTP_PROVIDERS } from '@angular/http';
@@ -38,7 +37,7 @@ describe('AlfrescoUploadDragArea', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{ provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock },
AlfrescoSettingsService,
AlfrescoAuthenticationService,
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
UploadService
@@ -16,11 +16,9 @@
*/
import { it, describe, inject, beforeEach, beforeEachProviders } from '@angular/core/testing';
import { EventEmitter } from '@angular/core';
import { UploadService } from './upload.service';
import { AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { AlfrescoSettingsServiceMock } from '../assets/AlfrescoSettingsService.service.mock';
import { HTTP_PROVIDERS } from '@angular/http';
import { EventEmitter } from '@angular/core';
declare let AlfrescoApi: any;
declare let jasmine: any;
@@ -40,9 +38,8 @@ describe('AlfrescoUploadService', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{ provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock },
{ provide: AlfrescoAuthenticationService, useClass: AlfrescoAuthenticationService },
AlfrescoSettingsService,
AlfrescoAuthenticationService,
UploadService
];
});
@@ -88,7 +85,7 @@ describe('AlfrescoUploadService', () => {
service.uploadFilesInTheQueue('fake-dir', emitter);
let request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe('fakehost/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children');
expect(request.url).toBe('http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children');
expect(request.method).toBe('POST');
jasmine.Ajax.requests.mostRecent().respondWith({
@@ -110,7 +107,7 @@ describe('AlfrescoUploadService', () => {
service.addToQueue(filesFake);
service.uploadFilesInTheQueue('', emitter);
expect(jasmine.Ajax.requests.mostRecent().url)
.toBe('fakehost/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children');
.toBe('http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/-root-/children');
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 404,
contentType: 'text/plain',
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -40,7 +40,7 @@
"ng2-alfresco-core": "^0.2.0",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-alfresco-viewer" : "file:../"
},
"devDependencies": {
@@ -57,9 +57,9 @@ class MyDemoApp {
token: string;
constructor(private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService) {
private settingsService: AlfrescoSettingsService) {
alfrescoSettingsService.ecmHost = this.ecmHost;
settingsService.ecmHost = this.ecmHost;
if (this.authService.getTicket()) {
this.token = this.authService.getTicket();
}
@@ -70,7 +70,7 @@ class MyDemoApp {
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
@@ -79,7 +79,7 @@ class MyDemoApp {
}
login() {
this.authService.login('admin', 'admin', ['ECM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -61,7 +61,7 @@
"ng2-alfresco-core": "0.2.0",
"ng2-translate": "2.2.2",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"systemjs": "0.19.27",
"core-js": "2.4.0",
@@ -1,36 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
@Injectable()
export class AlfrescoSettingsServiceMock {
static DEFAULT_HOST_ADDRESS: string = 'fakehost';
private providers: string[] = ['ECM', 'BPM'];
private _host: string = AlfrescoSettingsServiceMock.DEFAULT_HOST_ADDRESS;
public get ecmHost(): string {
return this._host;
}
getProviders(): string [] {
return this.providers;
}
}
@@ -23,20 +23,16 @@ import {PDFJSmock} from './assets/PDFJS.mock';
import {PDFViewermock} from './assets/PDFViewer.mock';
import {EventMock} from './assets/event.mock';
import {HTTP_PROVIDERS} from '@angular/http';
import {AlfrescoSettingsServiceMock} from '../src/assets/AlfrescoSettingsService.service.mock';
import {AlfrescoAuthenticationService, AlfrescoSettingsService} from 'ng2-alfresco-core';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
describe('PdfViewer', () => {
let pdfComponentFixture, element, component;
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock},
{provide: AlfrescoAuthenticationService, useClass: AlfrescoAuthenticationService}
AlfrescoSettingsService,
AlfrescoAuthenticationService
];
});
@@ -15,338 +15,216 @@
* limitations under the License.
*/
import { describe, expect, it, inject, beforeEachProviders } from '@angular/core/testing';
import { TestComponentBuilder } from '@angular/compiler/testing';
import { ViewerComponent } from './viewer.component';
import { EventMock } from './assets/event.mock';
import { HTTP_PROVIDERS } from '@angular/http';
import { AlfrescoSettingsServiceMock } from '../src/assets/AlfrescoSettingsService.service.mock';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
import {describe, expect, it, inject, beforeEachProviders, beforeEach} from '@angular/core/testing';
import {TestComponentBuilder} from '@angular/compiler/testing';
import {ViewerComponent} from './viewer.component';
import {EventMock} from './assets/event.mock';
import {AlfrescoAuthenticationService, AlfrescoSettingsService} from 'ng2-alfresco-core';
describe('ViewerComponent', () => {
describe('ViewerComponent', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock},
{provide: AlfrescoAuthenticationService, useClass: AlfrescoAuthenticationService}
];
});
let viewerComponentFixture, element, component;
describe('View', () => {
it('shadow overlay should be present if is overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = true;
beforeEachProviders(() => {
return [
AlfrescoSettingsService,
AlfrescoAuthenticationService
];
});
fixture.detectChanges();
beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then(fixture => {
viewerComponentFixture = fixture;
element = viewerComponentFixture.nativeElement;
component = viewerComponentFixture.componentInstance;
expect(element.querySelector('#viewer-shadow-transparent')).not.toBeNull();
});
}));
component.urlFile = 'fake-url-file';
component.overlayMode = true;
it('header should be present if is overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = true;
viewerComponentFixture.detectChanges();
});
}));
fixture.detectChanges();
describe('View', () => {
it('shadow overlay should be present if is overlay mode', () => {
expect(element.querySelector('#viewer-shadow-transparent')).not.toBeNull();
});
expect(element.querySelector('header')).not.toBeNull();
});
}));
it('header should be present if is overlay mode', () => {
expect(element.querySelector('header')).not.toBeNull();
});
it('header should be NOT be present if is not overlay mode', () => {
component.overlayMode = false;
it('header should be NOT be present if is not overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = false;
viewerComponentFixture.detectChanges();
fixture.detectChanges();
expect(element.querySelector('header')).toBeNull();
});
expect(element.querySelector('header')).toBeNull();
});
}));
it('Name File should be present if is overlay mode ', () => {
component.urlFile = 'http://localhost:9876/fake-url-file.pdf';
component.overlayMode = true;
it('Name File should be present if is overlay mode ', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'http://localhost:9876/fake-url-file.pdf';
component.overlayMode = true;
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('fake-url-file.pdf');
});
});
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('fake-url-file.pdf');
});
});
}));
it('Close button should be present if overlay mode', () => {
component.urlFile = 'fake-url-file';
component.overlayMode = true;
/* tslint:disable:max-line-length */
it('should pick up filename from the fileName property when specified', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'http://localhost:9876/fake-url-file.pdf';
component.fileName = 'My Example.pdf';
viewerComponentFixture.detectChanges();
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('My Example.pdf');
});
});
}));
expect(element.querySelector('#viewer-close-button')).not.toBeNull();
});
it('Close button should be present if overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = true;
it('Close button should be not present if is not overlay mode', () => {
component.urlFile = 'fake-url-file';
component.overlayMode = false;
fixture.detectChanges();
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-close-button')).not.toBeNull();
});
}));
expect(element.querySelector('#viewer-close-button')).toBeNull();
});
it('Close button should be not present if is not overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = false;
it('Click on close button should hide the viewer', () => {
component.urlFile = 'fake-url-file';
component.overlayMode = true;
fixture.detectChanges();
viewerComponentFixture.detectChanges();
element.querySelector('#viewer-close-button').click();
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
expect(element.querySelector('#viewer-close-button')).toBeNull();
});
}));
});
it('Esc button should not hide the viewerls if is not overlay mode', () => {
component.overlayMode = false;
it('Click on close button should hide the viewer', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = true;
component.urlFile = 'fake-url-file';
fixture.detectChanges();
element.querySelector('#viewer-close-button').click();
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
}));
viewerComponentFixture.detectChanges();
EventMock.keyDown(27);
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).not.toBeNull();
});
it('Esc button should not hide the viewerls if is not overlay mode', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.overlayMode = false;
it('Esc button should hide the viewer', () => {
component.urlFile = 'fake-url-file';
component.overlayMode = true;
component.urlFile = 'fake-url-file';
viewerComponentFixture.detectChanges();
EventMock.keyDown(27);
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
fixture.detectChanges();
EventMock.keyDown(27);
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).not.toBeNull();
});
}));
});
it('Esc button should hide the viewer', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let element = fixture.nativeElement;
let component = fixture.componentInstance;
component.urlFile = 'fake-url-file';
component.overlayMode = true;
describe('Attribute', () => {
it('Url File should be mandatory', () => {
component.showViewer = true;
component.urlFile = undefined;
fixture.detectChanges();
EventMock.keyDown(27);
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
}));
});
expect(() => {
component.ngOnChanges();
}).toThrow();
});
describe('Attribute', () => {
it('Url File should be mandatory', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
component.showViewer = true;
it('showViewer default value should be true', () => {
expect(component.showViewer).toBe(true);
});
expect(() => {
component.ngOnChanges();
}).toThrow();
});
}));
it('if showViewer value is false the viewer should be hide', () => {
component.urlFile = 'fake-url-file';
component.showViewer = false;
it('showViewer default value should be true', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
});
expect(component.showViewer).toBe(true);
});
}));
describe('Extension Type Test', () => {
it('if extension file is a pdf the pdf viewer should be loaded', (done) => {
component.urlFile = 'fake-url-file.pdf';
it('if showViewer value is false the viewer should be hide', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'fake-url-file';
component.showViewer = false;
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
done();
});
});
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
}));
});
it('if extension file is a image the img viewer should be loaded', (done) => {
component.urlFile = 'fake-url-file.png';
/* tslint:disable:max-line-length */
describe('Extension Type Test', () => {
it('if extension file is a pdf the pdf viewer should be loaded', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'fake-url-file.pdf';
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
done();
});
});
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
});
});
}));
it('if extension file is a not supported the not supported div should be loaded', (done) => {
component.urlFile = 'fake-url-file.unsupported';
/* tslint:disable:max-line-length */
it('if extension file is a image the img viewer should be loaded', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'fake-url-file.png';
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('not-supported-format')).not.toBeNull();
done();
});
});
});
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
});
});
}));
describe('MimeType handling', () => {
it('should display a PDF file identified by mimetype when the filename has no extension', (done) => {
component.urlFile = 'content';
component.mimeType = 'application/pdf';
/* tslint:disable:max-line-length */
it('if extension file is a not supported the not supported div should be loaded', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'fake-url-file.unsupported';
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
done();
});
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('not-supported-format')).not.toBeNull();
});
});
}));
});
});
/* tslint:disable:max-line-length */
describe('MimeType handling', () => {
it('should display a PDF file identified by mimetype when the filename has no extension', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'content';
component.mimeType = 'application/pdf';
it('should display a PDF file identified by mimetype when the file extension is wrong', (done) => {
component.urlFile = 'content.bin';
component.mimeType = 'application/pdf';
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
});
});
}));
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
done();
});
});
it('should display a PDF file identified by mimetype when the file extension is wrong', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'content.bin';
component.mimeType = 'application/pdf';
it('should display an image file identified by mimetype when the filename has no extension', (done) => {
component.urlFile = 'content';
component.mimeType = 'image/png';
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('pdf-viewer')).not.toBeNull();
});
});
}));
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
done();
});
});
it('should display an image file identified by mimetype when the filename has no extension', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'content';
component.mimeType = 'image/png';
it('should display a image file identified by mimetype when the file extension is wrong', (done) => {
component.urlFile = 'content.bin';
component.mimeType = 'image/png';
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
});
});
}));
it('should display a image file identified by mimetype when the file extension is wrong', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(ViewerComponent)
.then((fixture) => {
let component = fixture.componentInstance;
let element = fixture.nativeElement;
component.urlFile = 'content.bin';
component.mimeType = 'image/png';
component.ngOnChanges().then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
});
});
}));
});
});
component.ngOnChanges().then(() => {
viewerComponentFixture.detectChanges();
expect(element.querySelector('#viewer-image')).not.toBeNull();
done();
});
});
});
});
@@ -24,7 +24,7 @@
"label-undefined": true,
"max-line-length": [
true,
140
180
],
"member-ordering": [
true,
@@ -56,7 +56,7 @@ The following component needs to be added to your systemjs.config:
- ng2-translate
- ng2-alfresco-core
- ng2-alfresco-datatable
- ng2-alfresco-dataœtable
Please refer to the following example to have an idea of how your systemjs.config should look like :
@@ -37,7 +37,7 @@
"material-design-icons": "2.2.3",
"material-design-lite": "1.1.3",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "^0.2.0",
@@ -34,9 +34,9 @@ import { WEBSCRIPTCOMPONENT } from 'ng2-alfresco-webscript';
<label for="token"><b>Insert a valid access token / ticket:</b></label><br>
<input id="token" type="text" size="48" (change)="updateToken();documentList.reload()" [(ngModel)]="token"><br>
<label for="token"><b>Insert the ip of your Alfresco instance:</b></label><br>
<input id="token" type="text" size="48" (change)="updateHost();documentList.reload()" [(ngModel)]="host"><br><br>
<input id="token" type="text" size="48" (change)="updateHost();documentList.reload()" [(ngModel)]="ecmHost"><br><br>
<div *ngIf="!authenticated" style="color:#FF2323">
Authentication failed to ip {{ host }} with user: admin, admin, you can still try to add a valid token to perform
Authentication failed to ip {{ ecmHost }} with user: admin, admin, you can still try to add a valid token to perform
operations.
</div>
<hr>
@@ -76,9 +76,11 @@ class WebscriptDemo implements OnInit {
token: string;
constructor(private authService: AlfrescoAuthenticationService,
private alfrescoSettingsService: AlfrescoSettingsService) {
private settingsService: AlfrescoSettingsService) {
settingsService.ecmHost = this.ecmHost;
settingsService.setProviders('ECM');
alfrescoSettingsService.ecmHost = this.ecmHost;
if (this.authService.getTicket()) {
this.token = this.authService.getTicket();
}
@@ -89,7 +91,7 @@ class WebscriptDemo implements OnInit {
}
public updateHost(): void {
this.alfrescoSettingsService.ecmHost = this.ecmHost;
this.settingsService.ecmHost = this.ecmHost;
this.login();
}
@@ -98,7 +100,7 @@ class WebscriptDemo implements OnInit {
}
login() {
this.authService.login('admin', 'admin', ['ECM']).subscribe(
this.authService.login('admin', 'admin').subscribe(
token => {
console.log(token);
this.token = token;
@@ -44,7 +44,7 @@
"@angular/upgrade": "2.0.0-rc.3",
"systemjs": "0.19.27",
"core-js": "^2.4.0",
"alfresco-js-api": "^0.2.0",
"alfresco-js-api": "^0.3.0",
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "^0.2.0",
@@ -1,36 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Injectable } from '@angular/core';
@Injectable()
export class AlfrescoSettingsServiceMock {
static DEFAULT_HOST_ADDRESS: string = 'fakehost';
private providers: string[] = ['ECM', 'BPM'];
private _host: string = AlfrescoSettingsServiceMock.DEFAULT_HOST_ADDRESS;
public get ecmHost(): string {
return this._host;
}
getProviders(): string [] {
return this.providers;
}
}
@@ -18,8 +18,6 @@
import { describe, expect, it, inject, beforeEachProviders, beforeEach, afterEach, xit } from '@angular/core/testing';
import { TestComponentBuilder } from '@angular/compiler/testing';
import { WebscriptComponent } from '../src/webscript.component';
import { AlfrescoSettingsServiceMock } from '../src/assets/AlfrescoSettingsService.service.mock';
import { HTTP_PROVIDERS } from '@angular/http';
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
@@ -31,9 +29,8 @@ describe('Test ng2-alfresco-webscript', () => {
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
{provide: AlfrescoSettingsService, useClass: AlfrescoSettingsServiceMock},
{provide: AlfrescoAuthenticationService, useClass: AlfrescoAuthenticationService}
AlfrescoSettingsService,
AlfrescoAuthenticationService
];
});
@@ -88,7 +85,7 @@ describe('Test ng2-alfresco-webscript', () => {
component.ngOnChanges().then(() => {
webscriptComponentFixture.detectChanges();
let request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe('fakehost/alfresco/service/sample/folder/Company%20Home');
expect(request.url).toBe('http://localhost:8080/alfresco/service/sample/folder/Company%20Home');
done();
});
+6
View File
@@ -41,4 +41,10 @@ in the demo shell:
./start-linked.sh
```
* If you want to build all your local component:
```sh
./npm-buid-alll.sh
```
For development environment configuration please refer to [project docs](demo-shell-ng2/README.md).
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
npm install -g npm-check
echo 'start' > ../check-dependecies.log
for PACKAGE in \
ng2-activiti-form \
ng2-activiti-processlist \
ng2-activiti-tasklist \
ng2-alfresco-core \
ng2-alfresco-datatable \
ng2-alfresco-documentlist \
ng2-alfresco-login \
ng2-alfresco-search \
ng2-alfresco-upload \
ng2-alfresco-viewer \
ng2-alfresco-webscript
do
echo "====== Check component: ${PACKAGE} ====="
cd "$DIR/../ng2-components/${PACKAGE}"
echo "====== Check component: ${PACKAGE} =====" >> ../../check-dependecies.log
npm-check >> ../../check-dependecies.log
done
cd "$DIR/../demo-shell-ng2"
echo "====== Check component: ${PACKAGE} =====" >> ../check-dependecies.log
npm-check >> ../check-dependecies.log
echo "====== You can find the log in the file check-dependecies.log in the main root====="
cd ${DIR}