Commit 0df5a001 authored by Laurent's avatar Laurent

upgrade syracuse/ermes adapter

parent 5fc69b02
import {PortalAdapter} from './adapter';
import * as cheerio from 'cheerio';
import {Account, Loan} from '../../models';
import {WrongLoginPassword} from './wrong-login-password';
import * as papa from 'papaparse';
import {PortalAdapter} from './adapter'
import * as cheerio from 'cheerio'
import {Account, Loan} from '../../models'
import {WrongLoginPassword} from './wrong-login-password'
import * as papa from 'papaparse'
export class Ermes extends PortalAdapter {
protected _time;
protected _time
public setTime(time): Ermes {
this._time = time;
return this;
this._time = time
return this
}
public getTime(): number {
return this._time
? this._time
: (new Date()).getTime();
: (new Date()).getTime()
}
public getIdentifier(): string {
return 'ermes';
return 'ermes'
}
public getLabel(): string {
return 'Ermes';
return 'Ermes'
}
public updateCard(account: Account): Promise<any> {
account.setCardNumber(account.credentials['login']);
return Promise.resolve();
account.setCardNumber(account.credentials['login'])
return Promise.resolve()
}
public canHandleWebsite($): boolean {
return $('form[action="logon.aspx"]').length;
return $('form[action="logon.aspx"]').length
}
public searchUrl(account: Account, terms: string): Promise<string> {
return Promise.resolve(account.getUrl() + '/search.php?lookfor=' + terms);
return Promise.resolve(account.getUrl() + '/search.php?lookfor=' + terms)
}
public canSearch(): boolean {
return false;
return false
}
......@@ -55,18 +55,18 @@ export class Ermes extends PortalAdapter {
return this
._requestAccountCategory(account, 'Profile')
.then( (response) => {
let $ = cheerio.load(response.content.toJSON().d);
let label = $('span.user-name').text().trim();
let $ = cheerio.load(response.content.toJSON().d)
let label = $('span.user-name').text().trim()
return label
? label
: $('div.myaccount-profile h3').text().trim();
});
: $('div.myaccount-profile h3').text().trim()
})
}
protected _signIn(account): Promise<any> {
if (!(account.credentials['login'] && account.credentials['password']))
return Promise.reject(new WrongLoginPassword());
return Promise.reject(new WrongLoginPassword())
return this
.request(account,
......@@ -75,63 +75,64 @@ export class Ermes extends PortalAdapter {
content: "username=" + account.credentials['login'] + "&password=" + account.credentials['password'],
headers: {"Content-Type": "application/x-www-form-urlencoded" }
})
.then( (response) => { return this._handleSignIn(account, response); } );
.then( (response) => { return this._handleSignIn(account, response) } )
}
protected _handleSignIn(account, response): Promise<any> {
let datas = response.content.toJSON();
let datas = response.content.toJSON()
if (!datas.success)
return Promise.reject(new WrongLoginPassword());
return Promise.reject(new WrongLoginPassword())
account.beConnected();
return Promise.resolve();
account.beConnected()
return Promise.resolve()
}
protected _fetchLoans(account): Promise<Array<Loan>> {
let token = this.getTime();
return this._fetchLoansHTML(account)
/* let token = this.getTime()
return this
.request(account,
{ url: account.getUrl() + '/Default/Portal/Services/ilsclient.svc/ExportAccount?type=csv&sections=loans&Token=' + token })
.then( (response) => {
return response.statusCode == 404
? this._fetchLoansHTML(account)
: this._parseLoansCSV(account, response);
});
: this._parseLoansCSV(account, response)
})*/
}
protected _parseLoansCSV(account, response): Array<Loan> {
let loans: Array<Loan> = new Array<Loan>();
let loans: Array<Loan> = new Array<Loan>()
let datas = papa.parse(response.content.toString(),
{delimiter:';',
skipEmptyLines:true})['data'];
datas.shift();
{delimiter:'',
skipEmptyLines:true})['data']
datas.shift()
datas.forEach((elem) => {
loans.push(new Loan()
.setTitle(elem[0])
.setAuthor(elem[1])
.setDateDue(elem[9].split('/').reverse().join('-')));
});
return loans;
.setDateDue(elem[9].split('/').reverse().join('-')))
})
return loans
}
protected _fetchAccountPortalId(account: Account): Promise<any> {
if (account.credentials['portal_id'])
return Promise.resolve(account.credentials['portal_id']);
return Promise.resolve(account.credentials['portal_id'])
return this
.request(account,
{ url: account.getUrl() + '/my-account.aspx'})
.then( (response) => {
let portal_regex = /ErmesManager\.AccountPortalId = (\d+)/;
let portal_id = portal_regex.exec(response.content.toString())[1];
account.credentials['portal_id'] = portal_id;
return portal_id;
});
let portal_regex = /ErmesManager\.AccountPortalId = (\d+)/
let portal_id = portal_regex.exec(response.content.toString())[1]
account.credentials['portal_id'] = portal_id
return portal_id
})
}
......@@ -148,7 +149,7 @@ export class Ermes extends PortalAdapter {
"Content-Type": "application/json",
"Referer": account.getUrl() + '/my-account.aspx'
}})
});
})
}
......@@ -156,37 +157,53 @@ export class Ermes extends PortalAdapter {
return this
._requestAccountCategory(account, 'Loans')
.then( (response) => {
return this._parseLoansHTML(account, response);
});
return this._parseLoansHTML(account, response)
})
}
protected _parseLoansHTML(account, response): Array<Loan> {
let loans: Array<Loan> = new Array<Loan>();
let loans: Array<Loan> = new Array<Loan>()
let $ = cheerio.load(response.content.toJSON().d);
let datas = $('.loan-results li.loan-item');
let $ = cheerio.load(response.content.toJSON().d)
let datas = $('.loan-results li.loan-item')
datas.each((i, elem) => {
let node = $(elem);
let node = $(elem)
let title = node.find('.title[title]').attr('title')
let thumbnail = node.find('.vignette_document img').attr('src')
let record_link = node.find('a[href*="/rsc/"]').add('a[href*="/doc/"]').attr('href')
let record_search_id = /\/(rsc|doc\/[^\/]+)\/([a-zA-Z0-9]+)\//.exec(record_link)
let record_id = record_search_id ? record_search_id[2] : ''
let title = node.find('.title[title]').attr('title');
let author = node.find('.title[title] + p').text().split('.')[0].trim();
let loan_data = JSON.parse(node.find('.loan-data').text())
let date_due = loan_data.DateRetour.split('/').reverse().join('-');
let thumbnail = node.find('.vignette_document img').attr('src');
let record_link = node.find('a[href*="/rsc/"]').attr('href');
let record_search_id = /\/rsc\/([0-9]+)\//.exec(record_link);
let record_id = record_search_id ? record_search_id[1] : '';
let author = node.find('.vignette_document img')
.attr('alt')
.split('|')
.slice(-1)[0]
.trim();
if (!author) {
author = node.find('.title[title] + p').text().split('.')[0].trim()
}
let date_due = loan_data.DateRetour
? loan_data.DateRetour
: node.find('.dateretour .loan-info-value').text().trim().split(' ')[0].trim()
loans.push(new Loan()
.setLoanId(loan_data.HoldingId)
.setTitle(title)
.setAuthor(author)
.setDateDue(date_due)
.setDateDue(date_due.split('/').reverse().join('-'))
.setRecordId(record_id)
.setRecordUrl(record_link));
// .setRecordThumbnail(thumbnail));
});
return loans;
.setRecordUrl(record_link)
.setRecordThumbnail(thumbnail))
})
return loans
}
}
This diff is collapsed.
declare var describe, expect, it, before, beforeEach, chai: any;
declare var describe, expect, it, before, beforeEach, chai: any
import {Loan, Account, Database, WrongLoginPassword} from '../../models/';
import {Ermes} from '../../models/portal/ermes';
import {ErmesLoansWithSuccessfulLogin,
import {Loan, Account, Database, WrongLoginPassword} from '../../models/'
import {Ermes} from '../../models/portal/ermes'
import {ErmesLoansWithSuccessfulLoginCSV,
ErmesSignInWithSuccessfulLogin,
ErmesOldSignInWithSuccessfulLogin,
ErmesWithLoginError,
ErmesWithSuccessfulLoginNoCSV} from './ermes-fixtures';
ErmesLoansWithSuccessfulLoginV1,
ErmesLoansWithSuccessfulLoginV2,
ErmesLoansWithSuccessfulLoginV3} from './ermes-fixtures'
describe('Account on Ermes', () => {
let adapter: Ermes;
let db: Database;
let account: Account;
let time: number;
let adapter: Ermes
let db: Database
let account: Account
let time: number
beforeEach( () => {
db = Database.open('testdb').clear();
time = (new Date()).getTime();
adapter = (new Ermes()).setTime(time);
db = Database.open('testdb').clear()
time = (new Date()).getTime()
adapter = (new Ermes()).setTime(time)
account = (new Account())
.setUrl('ermes.fr')
.setCredentials({login: 'marco',
password: 'polo',
portal: 'ermes'});
portal: 'ermes'})
db.save(account);
});
db.save(account)
})
describe('With successful Login scenario', () => {
it('db should have two loans', () => {
let http = new ErmesLoansWithSuccessfulLogin('http://ermes.fr', time);
return adapter.setHTTP(http).refresh(account).then(() => {
let loans = db.findAll(Loan).sort((a, b) => {
return a.getDateDue().localeCompare(b.getDateDue());
});
// it('loans from CSV should save two loans in db', () => {
// let http = new ErmesLoansWithSuccessfulLoginCSV('http://ermes.fr', time)
// return adapter.setHTTP(http).refresh(account).then(() => {
// let loans = db.findAll(Loan).sort((a, b) => {
// return a.getDateDue().localeCompare(b.getDateDue())
// })
expect(loans).to.have.lengthOf(2);
expect(loans[0].getTitle()).to.equals('Copains');
expect(loans[0].getAuthor()).to.equals('Stehr, Frédéric');
expect(loans[0].getDateDue()).to.equals('2018-03-22');
});
});
// expect(loans).to.have.lengthOf(2)
// expect(loans[0].getTitle()).to.equals('Copains')
// expect(loans[0].getAuthor()).to.equals('Stehr, Frédéric')
// expect(loans[0].getDateDue()).to.equals('2018-03-22')
// })
// })
it('sign in should set account label to Marco Polo', () => {
let http = new ErmesSignInWithSuccessfulLogin('http://ermes.fr', time);
let http = new ErmesSignInWithSuccessfulLogin('http://ermes.fr', time)
return adapter.setHTTP(http).signIn(account).then(() => {
expect(account.label).to.equals('Marco POLO');
});
});
expect(account.label).to.equals('Marco POLO')
})
})
it('sign in on older Ermes should set account label to Marco Polo', () => {
let http = new ErmesOldSignInWithSuccessfulLogin('http://ermes.fr', time);
let http = new ErmesOldSignInWithSuccessfulLogin('http://ermes.fr', time)
return adapter.setHTTP(http).signIn(account).then(() => {
expect(account.label).to.equals('Marco POLO');
});
});
});
expect(account.label).to.equals('Marco POLO')
})
})
})
describe('With successful Login', () => {
it('v1 should have two loans', () => {
let http = new ErmesLoansWithSuccessfulLoginV1('http://ermes.fr', time)
return adapter.setHTTP(http).refresh(account).then(() => {
let loans = account.findLoans(db);
expect(loans).to.have.lengthOf(2)
expect(loans[0].getLoanId()).to.equals('2300454659')
expect(loans[0].getTitle()).to.equals('Sous les cahiers, la plage')
expect(loans[0].getAuthor()).to.equals('Coppée, Thierry')
expect(loans[0].getDateDue()).to.equals('2018-03-10')
expect(loans[0].getRecordThumbnail()).to.equals('http://marketplace.archimed.fr/Cover/CAECE/MONO/_3h0Q83cqExhhSLb297OlA2/9782847897784/MEDIUM')
expect(loans[0].getRecordId()).to.equals('389779')
expect(loans[0].getRecordUrl()).to.equals('http://ermes.fr/EXPLOITATION/rsc/389779/sous-les-cahiers-la-plage')
})
})
it('v2 should have one loan', () => {
let http = new ErmesLoansWithSuccessfulLoginV2('http://ermes.fr', time)
return adapter.setHTTP(http).refresh(account).then(() => {
let loans = account.findLoans(db);
expect(loans).to.have.lengthOf(1)
expect(loans[0].getLoanId()).to.equals('32272136414957')
expect(loans[0].getTitle()).to.equals('Copain des geeks')
expect(loans[0].getAuthor()).to.equals('Nathalie Lafargue. Auteur')
expect(loans[0].getDateDue()).to.equals('2018-07-24')
expect(loans[0].getRecordThumbnail()).to.equals('http://marketplace.archimed.fr/Cover/VPCO/MONO/EEJ5pTzUVIHLMPY8ccApeQ2/978-2-7459-8430-2/MEDIUM?fallback=https%3a%2f%2fermes.fr%2fui%2fskins%2fdefault%2fportal%2ffront%2fimages%2fGeneral%2fDocType%2fMONO_MEDIUM.png')
expect(loans[0].getRecordId()).to.equals('1107727')
expect(loans[0].getRecordUrl()).to.equals('https://ermes.fr/Default/doc/SYRACUSE/1107727/copain-des-geeks');
})
})
describe('With successful Login with no CSV available scenario', () => {
it('db should have two loans', () => {
let http = new ErmesWithSuccessfulLoginNoCSV('http://ermes.fr', time);
it('v3 should have one loan', () => {
let http = new ErmesLoansWithSuccessfulLoginV3('http://ermes.fr', time)
return adapter.setHTTP(http).refresh(account).then(() => {
let loans = db.findAll(Loan).sort((a, b) => {
return a.getDateDue().localeCompare(b.getDateDue());
});
let loans = account.findLoans(db);
expect(loans).to.have.lengthOf(2);
expect(loans[0].getTitle()).to.equals('Sous les cahiers, la plage');
expect(loans[0].getAuthor()).to.equals('Coppée, Thierry');
expect(loans[0].getDateDue()).to.equals('2018-03-10');
// expect(loans[0].getRecordThumbnail()).to.equals('http://marketplace.archimed.fr/Cover/CAECE/MONO/_3h0Q83cqExhhSLb297OlA2/9782847897784/MEDIUM');
expect(loans[0].getRecordId()).to.equals('389779');
});
});
});
expect(loans).to.have.lengthOf(1)
expect(loans[0].getLoanId()).to.equals('9159344')
expect(loans[0].getTitle()).to.equals('Berceuses de toujours : réadaptation en berceuses des plus belles chansons d\'enfants. 1')
expect(loans[0].getAuthor()).to.equals('Chantal')
expect(loans[0].getDateDue()).to.equals('2018-06-10')
expect(loans[0].getRecordThumbnail()).to.equals('http://marketplace.archimed.fr/Cover/CACM/AUDI/2HasC_PL5occK5oGjNwLHQ2/3770000853049/MEDIUM?fallback=http%3a%2f%2fermes.fr%2fui%2fskins%2fdefault%2fportal%2ffront%2fimages%2fGeneral%2fDocType%2fAUDI_MEDIUM.png')
expect(loans[0].getRecordId()).to.equals('frOr1434603153')
expect(loans[0].getRecordUrl()).to.equals('http://ermes.fr/Default/doc/ORPHEE/frOr1434603153/berceuses-de-toujours-readaptation-en-berceuses-des-plus-belles-chansons-d-enfants-1');
})
})
})
it('without wrong credentials should raise wrong login password', () => {
let http = new ErmesWithLoginError('http://ermes.fr');
let http = new ErmesWithLoginError('http://ermes.fr')
return adapter.setHTTP(http).refresh(account).then(
() => {
expect.fail('Error should be thrown');
expect.fail('Error should be thrown')
},
(error) => {
error.should.be.an.instanceOf(WrongLoginPassword);
error.should.be.an.instanceOf(WrongLoginPassword)
}
);
)
})
});
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment