Files

50 lines
6.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,/полный текст недоступен/);
});