50 lines
6.2 KiB
TypeScript
50 lines
6.2 KiB
TypeScript
import assert from 'node:assert/strict';
|
||
import {test} from 'node:test';
|
||
import {accessMessage,classifyResponse,purchaseOffer,checkCurrent,result,evidenceUrl,RULES_VERSION} from '../lib/access.ts';
|
||
const lan='https://e.lanbook.com/book/111431',urait='https://urait.ru/course-viewer/6BDE5BCD-49B3-4DCD-B6BF-F91BF5F4657E';
|
||
const html=(body:string)=>'<html><title>Book</title><body><main>'+body+'</main></body></html>';
|
||
const classify=(body:string,url=lan)=>classifyResponse(url,{url,body:html(body),code:200,type:'text/html'});
|
||
const offer='<div class="book-offers__item">Доступ онлайн<div class="book-offers__price">от 156 ₽</div><span class="book-offers__ctrl" data-id="372956">В корзину</span></div>';
|
||
|
||
test('Lanbook denial is unavailable with an explicit login reason and evidence',()=>{
|
||
const check=classify('<div class="lan-callout lan-callout-danger"><h4>Чтение книги недоступно</h4><p>Для доступа к чтению книги необходимо авторизоваться.</p></div>');
|
||
assert.equal(check.status,'auth');assert.equal(check.reason,'Для чтения книги требуется авторизация.');assert.match(check.evidence!.text,/необходимо авторизоваться/);assert.equal(check.profile,'anonymous');
|
||
});
|
||
test('Urait requires both login and subscription; PDF prohibition alone is insufficient',()=>{
|
||
const check=accessMessage(urait,'Чтобы получить полный доступ к курсам, авторизуйтесь на аккаунте с подпиской учебного заведения или личной подпиской.')!;
|
||
assert.equal(check.status,'restricted');assert.equal(check.reason,'Для чтения книги требуются авторизация и подписка.');
|
||
assert.equal(accessMessage(urait,'Оплаченный доступ к контенту предоставляется только на платформе. Скачивание контента в PDF не доступно.'),null);
|
||
});
|
||
test('Znanium withdrawn and priced online access are different evidence',()=>{
|
||
assert.equal(classify('Данная публикация изъята из фонда.','https://znanium.ru/catalog/document?pid=1040849').reason,'Публикация изъята из фонда.');
|
||
const paid=purchaseOffer('https://znanium.ru/catalog/document?id=372956',offer)!;assert.equal(paid.status,'restricted');assert.match(paid.reason,/покупка онлайн-доступа/);assert.match(paid.evidence!.url,/id=372956/);
|
||
assert.equal(purchaseOffer('https://znanium.ru/catalog/document?id=372956',offer.replace('Доступ онлайн','Печатная книга')),null);
|
||
assert.equal(purchaseOffer('https://znanium.ru/catalog/document?id=999',offer),null);
|
||
assert.equal(purchaseOffer('https://znanium.ru/catalog/document?id=372956',offer.replace('156','0')),null);
|
||
});
|
||
test('iBooks uses the reader denial rather than a login button on the catalogue card',()=>{
|
||
const check=accessMessage('https://ibooks.ru/bookshelf/356956/reading','Для продолжения работы с сайтом, пожалуйста, войдите в систему')!;
|
||
assert.equal(check.status,'auth');assert.equal(classify('<button>Войти</button><h1>Linux API</h1>Аннотация','https://ibooks.ru/products/356956').status,'unknown');
|
||
const url='https://ibooks.ru/bookshelf/356956/reading';assert.equal(classifyResponse(url,{url,body:html('Для продолжения работы с сайтом, пожалуйста, войдите в систему'),code:403,type:'text/html'}).status,'auth');
|
||
});
|
||
test('Springer requires an eBook purchase offer, not the paper edition price',()=>{
|
||
const url='https://link.springer.com/book/10.1007/978-3-642-17545-9',block='<div class="app-article-access"><h2>Access this book</h2><div class="buying-option"><span>eBook</span><span class="price-amount">EUR 117.69</span><button>Buy eBook</button></div></div>';
|
||
assert.equal(purchaseOffer(url,block)?.status,'restricted');
|
||
assert.equal(purchaseOffer(url,block.replaceAll('eBook','Hardcover Book')),null);
|
||
assert.equal(purchaseOffer(url,block.replace('Access this book','This is an open access book')),null);
|
||
});
|
||
test('hidden templates, general login, annotations and successful HTTP do not confirm access',()=>{
|
||
for(const body of ['<h1>Book</h1>Аннотация','<header><input type="password"/>Для чтения авторизуйтесь</header><p>Book card</p>','<div hidden>Для чтения необходимо авторизоваться</div>','<div class="hidden">Для чтения необходимо авторизоваться</div>','<div style="display:none">Для чтения необходимо авторизоваться</div>','<div style="visibility: hidden !important">Для чтения необходимо авторизоваться</div>'])assert.equal(classify(body).status,'unknown');
|
||
});
|
||
test('old rule versions and expired checks are invalidated independently of course content',()=>{
|
||
const now=Date.now(),fresh=result(lan,'auth','Login');assert.equal(checkCurrent(fresh,now),true);
|
||
assert.equal(checkCurrent({...fresh,rulesVersion:undefined},now),false);assert.equal(checkCurrent({...fresh,rulesVersion:'old'},now),false);
|
||
assert.equal(checkCurrent({...fresh,checkedAt:new Date(now-86400001).toISOString()},now),false);
|
||
assert.equal(checkCurrent({...fresh,status:'unknown',checkedAt:new Date(now-600001).toISOString()},now),false);assert.equal(fresh.rulesVersion,RULES_VERSION);
|
||
});
|
||
test('evidence URLs retain book identifiers while discarding tokens and tracking',()=>assert.equal(evidenceUrl('https://znanium.ru/catalog/document?id=372956&token=secret&utm_source=x#foo'),'https://znanium.ru/catalog/document?id=372956'));
|
||
test('BOOK.ru guest preview is unavailable even when twenty pages can be read',()=>{
|
||
const check=accessMessage('https://book.ru/book/940586','Перейти в модуль чтения в гостевом режиме, где доступны только 20 страниц книги.')!;
|
||
assert.equal(check.status,'restricted');assert.match(check.reason,/до 20 страниц/);assert.match(check.reason,/полный текст недоступен/);
|
||
});
|