dongnelibrary 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/package.json +12 -13
- package/src/cli.js +16 -17
- package/src/dongnelibrary.js +2 -0
- package/src/library/gg.js +3 -0
- package/src/library/gunpo.js +4 -1
- package/src/library/hscity.js +9 -3
- package/src/library/osan.js +3 -0
- package/src/library/snlib.js +5 -0
- package/src/library/suwon.js +3 -0
- package/src/library/yongin.js +3 -0
- package/test/dongne.spec.js +26 -29
- package/test/helpers/libraryTestSuite.js +173 -113
- package/test/util.spec.js +4 -3
package/README.md
CHANGED
|
@@ -78,10 +78,11 @@ dl.search(
|
|
|
78
78
|
|
|
79
79
|
- [경기교육통합도서관][gg-url] (경기중앙교육도서관,경기평택교육도서관,경기광주교육도서관,경기여주가남교육도서관,경기포천교육도서관,경기김포교육도서관,경기과천교육도서관,경기성남교육도서관,경기화성교육도서관,경기의정부교육도서관,경기평생교육학습관)
|
|
80
80
|
- [군포시도서관][gunpo-url] (산본도서관,당동도서관,대야도서관,어린이도서관,이동도서관,군포중앙도서관,누리천문대,시청북카페밥상머리,부곡도서관,당정문화도서관,동화나무어린이도서관,금정작은도서관,재궁꿈나무도서관,궁내동작은도서관,노루목작은도서관,버드나무에부는바람작은도서관,꿈쟁이도서관,우리마을도서관,북카페사랑아이엔지,산본역도서관,하늘정원작은도서관,꿈이지,꿈드림작은도서관,여담작은도서관)
|
|
81
|
-
- [성남시도서관][snlib-url] (
|
|
81
|
+
- [성남시도서관][snlib-url] (논골도서관,중원어린이도서관,성남중앙도서관,분당도서관,고등도서관,구미도서관,해오름도서관,중원도서관,무지개도서관,수내도서관,판교도서관,위례도서관,수정도서관,책테마파크도서관,운중도서관,서현도서관,복정도서관,판교어린이도서관)
|
|
82
82
|
- [오산시도서관][osan-url] (오산중앙도서관,꿈두레도서관,초평도서관,햇살마루도서관,청학도서관,양산도서관,소리울도서관,무지개도서관,고현초꿈키움도서관,쌍용예가시민개방도서관)
|
|
83
|
-
- [화성시립도서관][hscity-url] (
|
|
83
|
+
- [화성시립도서관][hscity-url] (남양도서관,태안도서관,삼괴도서관,병점도서관,샘내도서관,두빛나래어린이도서관,봉담도서관,둥지나래어린이도서관,목동이음터도서관,기아행복마루도서관,화성동탄중앙도서관,송산도서관,정남도서관,비봉도서관,진안도서관,중앙이음터도서관,양감도서관,다원이음터도서관,송린이음터도서관,팔탄도서관,마도도서관,봉담커피앤북도서관,왕배푸른숲도서관,노을빛도서관,서연이음터도서관,호연이음터도서관,향남복합문화센터도서관,봉담와우도서관,늘봄이음터도서관,달빛나래어린이도서관)
|
|
84
84
|
- [수원시도서관][suwon-url] (선경도서관,수원중앙도서관,창룡도서관,화서다산도서관,호매실도서관,서수원도서관,한림도서관,버드내도서관,북수원도서관,대추골도서관,일월도서관,광교홍재도서관,태장마루도서관,광교푸른숲도서관,매여울도서관,망포글빛도서관,슬기샘도서관,지혜샘어린이도서관,바른샘어린이도서관,한아름도서관,반달어린이도서관,사랑샘도서관,희망샘도서관)
|
|
85
|
+
- [용인시도서관][yongin-url] (수지도서관,구성도서관,기흥도서관,남사도서관,동백도서관,동천도서관,모현도서관,보라도서관,상현도서관,서농도서관,성복도서관,용인중앙도서관,양지해밀도서관,영덕도서관,죽전도서관,청덕도서관,포곡도서관,흥덕도서관)
|
|
85
86
|
|
|
86
87
|
## 마무리
|
|
87
88
|
|
|
@@ -98,6 +99,7 @@ dl.search(
|
|
|
98
99
|
npm run osan # 오산시 도서관
|
|
99
100
|
npm run snlib # 성남시 도서관
|
|
100
101
|
npm run suwon # 수원시 도서관
|
|
102
|
+
npm run yongin # 용인시 도서관
|
|
101
103
|
|
|
102
104
|
[dongnelibraryspa]: https://github.com/afrontend/dongnelibraryspa "AngularJS, Foundation을 사용한 Web UI"
|
|
103
105
|
[npm-image]: https://img.shields.io/npm/v/dongnelibrary.svg
|
|
@@ -110,4 +112,5 @@ dl.search(
|
|
|
110
112
|
[osan-url]: https://www.osanlibrary.go.kr
|
|
111
113
|
[snlib-url]: https://www.snlib.go.kr
|
|
112
114
|
[suwon-url]: https://www.suwonlib.go.kr
|
|
115
|
+
[yongin-url]: https://lib.yongin.go.kr
|
|
113
116
|
[sample-url]: https://npm.runkit.com/dongnelibrary
|
package/package.json
CHANGED
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=18.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.12",
|
|
7
7
|
"description": "책을 빌릴 수 있는지 확인한다.",
|
|
8
8
|
"main": "src/dongnelibrary.js",
|
|
9
9
|
"bin": {
|
|
10
10
|
"dongnelibrary": "src/cli.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"test": "
|
|
14
|
-
"dongne": "
|
|
15
|
-
"gg": "
|
|
16
|
-
"gunpo": "
|
|
17
|
-
"hscity": "
|
|
18
|
-
"osan": "
|
|
19
|
-
"snlib": "
|
|
20
|
-
"suwon": "
|
|
21
|
-
"yongin": "
|
|
13
|
+
"test": "node --test test/*.spec.js",
|
|
14
|
+
"dongne": "node --test test/dongne.spec.js",
|
|
15
|
+
"gg": "node --test test/gg.spec.js",
|
|
16
|
+
"gunpo": "node --test test/gunpo.spec.js",
|
|
17
|
+
"hscity": "node --test test/hscity.spec.js",
|
|
18
|
+
"osan": "node --test test/osan.spec.js",
|
|
19
|
+
"snlib": "node --test test/snlib.spec.js",
|
|
20
|
+
"suwon": "node --test test/suwon.spec.js",
|
|
21
|
+
"yongin": "node --test test/yongin.spec.js"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
@@ -44,8 +44,7 @@
|
|
|
44
44
|
"homepage": "https://github.com/afrontend/dongnelibrary#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"acorn": ">=5.7.4",
|
|
47
|
-
"minimist": ">=1.2.2"
|
|
48
|
-
"mocha": "^10.2.0"
|
|
47
|
+
"minimist": ">=1.2.2"
|
|
49
48
|
},
|
|
50
49
|
"tonicExampleFilename": "src/example.js",
|
|
51
50
|
"dependencies": {
|
|
@@ -54,7 +53,7 @@
|
|
|
54
53
|
"commander": "^2.11.0",
|
|
55
54
|
"configstore": "^4.0.0",
|
|
56
55
|
"figlet": "^1.2.1",
|
|
57
|
-
"inquirer": "^
|
|
56
|
+
"@inquirer/prompts": "^7.0.0",
|
|
58
57
|
"jquery": "^3.7.1",
|
|
59
58
|
"jsdom": "^21.1.1",
|
|
60
59
|
"lodash": "^4.17.20",
|
package/src/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const Configstore = require("configstore");
|
|
3
3
|
const colors = require("colors");
|
|
4
4
|
const figlet = require("figlet");
|
|
5
|
-
const
|
|
5
|
+
const { select, input } = require("@inquirer/prompts");
|
|
6
6
|
const program = require("commander");
|
|
7
7
|
const dl = require("./dongnelibrary");
|
|
8
8
|
const util = require("./util");
|
|
@@ -45,7 +45,10 @@ const MARKS = {
|
|
|
45
45
|
notOk: "✖ ",
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const printBooks = ({ booklist }) => {
|
|
48
|
+
const printBooks = ({ booklist, homeUrl }) => {
|
|
49
|
+
if (homeUrl) {
|
|
50
|
+
console.log(colors.yellow(`[${homeUrl}]`));
|
|
51
|
+
}
|
|
49
52
|
for (const { libraryName, exist, title, bookUrl } of booklist) {
|
|
50
53
|
const mark = exist ? ` ${MARKS.ok} ` : ` ${colors.red(MARKS.notOk)} `;
|
|
51
54
|
console.log(`${cutTail(libraryName, "도서관")}${mark}${title}`);
|
|
@@ -108,21 +111,17 @@ const printSearchSummary = (results) => {
|
|
|
108
111
|
|
|
109
112
|
const promptForSearchOptions = async () => {
|
|
110
113
|
introMessage("Dongne Library");
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
message: "책 이름은?",
|
|
123
|
-
default: config.getTitle(),
|
|
124
|
-
},
|
|
125
|
-
]);
|
|
114
|
+
|
|
115
|
+
const library = await select({
|
|
116
|
+
message: "도서관 이름은?",
|
|
117
|
+
choices: dl.getLibraryNames().map((name) => ({ name, value: name })),
|
|
118
|
+
default: config.getLibrary(),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const title = await input({
|
|
122
|
+
message: "책 이름은?",
|
|
123
|
+
default: config.getTitle(),
|
|
124
|
+
});
|
|
126
125
|
|
|
127
126
|
config.setLibrary(library);
|
|
128
127
|
config.setTitle(title);
|
package/src/dongnelibrary.js
CHANGED
|
@@ -13,6 +13,7 @@ const libraryList = LIBRARY_MODULES.flatMap((module) =>
|
|
|
13
13
|
module.getLibraryNames().map((name) => ({
|
|
14
14
|
name,
|
|
15
15
|
search: module.search,
|
|
16
|
+
homeUrl: module.homeUrl,
|
|
16
17
|
})),
|
|
17
18
|
);
|
|
18
19
|
|
|
@@ -60,6 +61,7 @@ const searchLibrary = (lib, title) =>
|
|
|
60
61
|
result: {
|
|
61
62
|
title,
|
|
62
63
|
libraryName: lib.name,
|
|
64
|
+
homeUrl: lib.homeUrl,
|
|
63
65
|
totalBookCount: data.totalBookCount,
|
|
64
66
|
startPage: data.startPage,
|
|
65
67
|
booklist: getSortedBooks(data.booklist),
|
package/src/library/gg.js
CHANGED
|
@@ -3,6 +3,8 @@ const jquery = require("jquery");
|
|
|
3
3
|
const { get } = require("../http");
|
|
4
4
|
const { JSDOM } = require("jsdom");
|
|
5
5
|
|
|
6
|
+
const homeUrl = "https://lib.goe.go.kr";
|
|
7
|
+
|
|
6
8
|
const libraryList = [
|
|
7
9
|
{ code: "MA", name: "경기중앙교육도서관" },
|
|
8
10
|
{ code: "MB", name: "경기평택교육도서관" },
|
|
@@ -108,6 +110,7 @@ async function search(opt, getBook) {
|
|
|
108
110
|
|
|
109
111
|
module.exports = {
|
|
110
112
|
search,
|
|
113
|
+
homeUrl,
|
|
111
114
|
getLibraryNames: function () {
|
|
112
115
|
return getLibraryNames(libraryList);
|
|
113
116
|
},
|
package/src/library/gunpo.js
CHANGED
|
@@ -2,6 +2,8 @@ const { get } = require("../http");
|
|
|
2
2
|
const _ = require("lodash");
|
|
3
3
|
const getLibraryNames = require("../util.js").getLibraryNames;
|
|
4
4
|
|
|
5
|
+
const homeUrl = "https://www.gunpolib.go.kr";
|
|
6
|
+
|
|
5
7
|
const libraryList = [
|
|
6
8
|
{ code: "1", name: "산본도서관" },
|
|
7
9
|
{ code: "2", name: "당동도서관" },
|
|
@@ -40,7 +42,7 @@ function getBookList(json) {
|
|
|
40
42
|
title: book.titleStatement,
|
|
41
43
|
exist: book.branchVolumes.some((vol) => vol.cState.includes("대출가능")),
|
|
42
44
|
libraryName: book.branchVolumes.map((vol) => vol.name).join(","),
|
|
43
|
-
bookUrl: book.id ? `https://www.gunpolib.go.kr/#/
|
|
45
|
+
bookUrl: book.id ? `https://www.gunpolib.go.kr/#/search/detail/${book.id}` : "",
|
|
44
46
|
};
|
|
45
47
|
});
|
|
46
48
|
}
|
|
@@ -98,6 +100,7 @@ async function search(opt, getBook) {
|
|
|
98
100
|
|
|
99
101
|
module.exports = {
|
|
100
102
|
search,
|
|
103
|
+
homeUrl,
|
|
101
104
|
getLibraryNames: function () {
|
|
102
105
|
return getLibraryNames(libraryList);
|
|
103
106
|
},
|
package/src/library/hscity.js
CHANGED
|
@@ -3,18 +3,20 @@ const jquery = require("jquery");
|
|
|
3
3
|
const { post } = require("../http");
|
|
4
4
|
const { JSDOM } = require("jsdom");
|
|
5
5
|
|
|
6
|
+
const homeUrl = "https://hscitylib.or.kr";
|
|
7
|
+
|
|
6
8
|
const libraryList = [
|
|
7
9
|
{ code: "MA", name: "남양도서관" },
|
|
8
10
|
{ code: "MB", name: "태안도서관" },
|
|
9
11
|
{ code: "MC", name: "삼괴도서관" },
|
|
10
12
|
{ code: "MD", name: "병점도서관" },
|
|
11
13
|
{ code: "ME", name: "샘내도서관" },
|
|
12
|
-
{ code: "MF", name: "
|
|
14
|
+
{ code: "MF", name: "두빛나래어린이도서관" },
|
|
13
15
|
{ code: "MG", name: "봉담도서관" },
|
|
14
|
-
{ code: "MH", name: "
|
|
16
|
+
{ code: "MH", name: "둥지나래어린이도서관" },
|
|
15
17
|
{ code: "MI", name: "목동이음터도서관" },
|
|
16
18
|
{ code: "MJ", name: "기아행복마루도서관" },
|
|
17
|
-
{ code: "MK", name: "
|
|
19
|
+
{ code: "MK", name: "화성동탄중앙도서관" },
|
|
18
20
|
{ code: "ML", name: "송산도서관" },
|
|
19
21
|
{ code: "MM", name: "정남도서관" },
|
|
20
22
|
{ code: "MN", name: "비봉도서관" },
|
|
@@ -30,7 +32,10 @@ const libraryList = [
|
|
|
30
32
|
{ code: "MX", name: "노을빛도서관" },
|
|
31
33
|
{ code: "MY", name: "서연이음터도서관" },
|
|
32
34
|
{ code: "MZ", name: "호연이음터도서관" },
|
|
35
|
+
{ code: "NA", name: "향남복합문화센터도서관" },
|
|
36
|
+
{ code: "NB", name: "봉담와우도서관" },
|
|
33
37
|
{ code: "TA", name: "늘봄이음터도서관" },
|
|
38
|
+
{ code: "TB", name: "달빛나래어린이도서관" },
|
|
34
39
|
];
|
|
35
40
|
|
|
36
41
|
function getLibraryCode(libraryName) {
|
|
@@ -116,6 +121,7 @@ async function search(opt, getBook) {
|
|
|
116
121
|
|
|
117
122
|
module.exports = {
|
|
118
123
|
search,
|
|
124
|
+
homeUrl,
|
|
119
125
|
getLibraryNames: function () {
|
|
120
126
|
return getLibraryNames(libraryList);
|
|
121
127
|
},
|
package/src/library/osan.js
CHANGED
|
@@ -2,6 +2,8 @@ const getLibraryNames = require("../util.js").getLibraryNames;
|
|
|
2
2
|
const { get } = require("../http");
|
|
3
3
|
const { JSDOM } = require("jsdom");
|
|
4
4
|
|
|
5
|
+
const homeUrl = "https://www.osanlibrary.go.kr";
|
|
6
|
+
|
|
5
7
|
const libraryList = [
|
|
6
8
|
{ code: "MA", name: "오산중앙도서관" },
|
|
7
9
|
{ code: "MG", name: "꿈두레도서관" },
|
|
@@ -139,6 +141,7 @@ async function search(opt, getBook) {
|
|
|
139
141
|
|
|
140
142
|
module.exports = {
|
|
141
143
|
search,
|
|
144
|
+
homeUrl,
|
|
142
145
|
getLibraryNames: function () {
|
|
143
146
|
return getLibraryNames(libraryList);
|
|
144
147
|
},
|
package/src/library/snlib.js
CHANGED
|
@@ -3,15 +3,19 @@ const jquery = require("jquery");
|
|
|
3
3
|
const { get } = require("../http");
|
|
4
4
|
const { JSDOM } = require("jsdom");
|
|
5
5
|
|
|
6
|
+
const homeUrl = "https://www.snlib.go.kr";
|
|
7
|
+
|
|
6
8
|
const libraryList = [
|
|
7
9
|
{ code: "BF", name: "논골도서관" },
|
|
8
10
|
{ code: "CK", name: "중원어린이도서관" },
|
|
9
11
|
{ code: "MA", name: "성남중앙도서관" },
|
|
10
12
|
{ code: "MB", name: "분당도서관" },
|
|
13
|
+
{ code: "MD", name: "고등도서관" },
|
|
11
14
|
{ code: "MG", name: "구미도서관" },
|
|
12
15
|
{ code: "MH", name: "해오름도서관" },
|
|
13
16
|
{ code: "MJ", name: "중원도서관" },
|
|
14
17
|
{ code: "MM", name: "무지개도서관" },
|
|
18
|
+
{ code: "MO", name: "수내도서관" },
|
|
15
19
|
{ code: "MP", name: "판교도서관" },
|
|
16
20
|
{ code: "MR", name: "위례도서관" },
|
|
17
21
|
{ code: "MS", name: "수정도서관" },
|
|
@@ -118,6 +122,7 @@ async function search(opt, getBook) {
|
|
|
118
122
|
|
|
119
123
|
module.exports = {
|
|
120
124
|
search,
|
|
125
|
+
homeUrl,
|
|
121
126
|
getLibraryNames: function () {
|
|
122
127
|
return getLibraryNames(libraryList);
|
|
123
128
|
},
|
package/src/library/suwon.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const getLibraryNames = require("../util.js").getLibraryNames;
|
|
2
2
|
const { createSession } = require("../http");
|
|
3
3
|
|
|
4
|
+
const homeUrl = "https://www.suwonlib.go.kr";
|
|
5
|
+
|
|
4
6
|
const libraryList = [
|
|
5
7
|
{ code: "141025", name: "선경도서관" },
|
|
6
8
|
{ code: "141024", name: "수원중앙도서관" },
|
|
@@ -143,6 +145,7 @@ async function search(opt, getBook) {
|
|
|
143
145
|
|
|
144
146
|
module.exports = {
|
|
145
147
|
search,
|
|
148
|
+
homeUrl,
|
|
146
149
|
getLibraryNames: function () {
|
|
147
150
|
return getLibraryNames(libraryList);
|
|
148
151
|
},
|
package/src/library/yongin.js
CHANGED
|
@@ -2,6 +2,8 @@ const getLibraryNames = require("../util.js").getLibraryNames;
|
|
|
2
2
|
const { get } = require("../http");
|
|
3
3
|
const { JSDOM } = require("jsdom");
|
|
4
4
|
|
|
5
|
+
const homeUrl = "https://lib.yongin.go.kr";
|
|
6
|
+
|
|
5
7
|
const libraryList = [
|
|
6
8
|
// Public libraries (시립도서관)
|
|
7
9
|
{ code: "MB", name: "수지도서관" },
|
|
@@ -176,6 +178,7 @@ async function search(opt, getBook) {
|
|
|
176
178
|
|
|
177
179
|
module.exports = {
|
|
178
180
|
search,
|
|
181
|
+
homeUrl,
|
|
179
182
|
getLibraryNames: function () {
|
|
180
183
|
return getLibraryNames(libraryList);
|
|
181
184
|
},
|
package/test/dongne.spec.js
CHANGED
|
@@ -1,36 +1,33 @@
|
|
|
1
|
+
const { describe, it } = require("node:test");
|
|
1
2
|
const dl = require("../src/dongnelibrary");
|
|
2
3
|
const assert = require("assert");
|
|
3
4
|
|
|
4
|
-
describe("dongnelibrary test",
|
|
5
|
-
describe("search in four libraries",
|
|
6
|
-
this.timeout(20000);
|
|
5
|
+
describe("dongnelibrary test", () => {
|
|
6
|
+
describe("search in four libraries", () => {
|
|
7
7
|
const libNameArray = ["여주", "성남", "판교", "선경"];
|
|
8
|
-
it("-l " + libNameArray.join(","),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
assert.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
done();
|
|
32
|
-
},
|
|
33
|
-
);
|
|
8
|
+
it("-l " + libNameArray.join(","), { timeout: 20000 }, () => {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
dl.search(
|
|
11
|
+
{
|
|
12
|
+
title: "자바스크립트",
|
|
13
|
+
libraryName: libNameArray,
|
|
14
|
+
},
|
|
15
|
+
(err, book) => {
|
|
16
|
+
if (err) {
|
|
17
|
+
assert.fail(err.msg);
|
|
18
|
+
}
|
|
19
|
+
assert.notEqual(book.booklist.length, 0);
|
|
20
|
+
},
|
|
21
|
+
(err, books) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
assert.fail(err.msg);
|
|
24
|
+
reject(err);
|
|
25
|
+
}
|
|
26
|
+
assert.equal(books.length, 4);
|
|
27
|
+
resolve();
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
});
|
|
34
31
|
});
|
|
35
32
|
});
|
|
36
33
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { describe, it } = require("node:test");
|
|
1
2
|
const assert = require("assert").strict;
|
|
2
3
|
const util = require("../../src/util.js");
|
|
3
4
|
|
|
@@ -10,143 +11,202 @@ function createLibraryTestSuite(lib, description) {
|
|
|
10
11
|
const libraryNames = lib.getLibraryNames();
|
|
11
12
|
const firstLibraryName = libraryNames[0];
|
|
12
13
|
|
|
13
|
-
describe(`${description} (제한시간 20초)`,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
it("Show library list", function (done) {
|
|
14
|
+
describe(`${description} (제한시간 20초)`, () => {
|
|
15
|
+
it("Show library list", { timeout: 20000 }, () => {
|
|
17
16
|
assert.ok(libraryNames.length > 1);
|
|
18
|
-
done();
|
|
19
17
|
});
|
|
20
18
|
|
|
21
|
-
it("Use empty book title",
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
it("Use invalid book title", function (done) {
|
|
40
|
-
lib.search(
|
|
41
|
-
{
|
|
42
|
-
title: "zyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyz",
|
|
43
|
-
libraryName: firstLibraryName,
|
|
44
|
-
startPage: 1,
|
|
45
|
-
},
|
|
46
|
-
function (err, book) {
|
|
47
|
-
if (err) {
|
|
48
|
-
assert.fail("must have an empty booklist");
|
|
49
|
-
}
|
|
50
|
-
assert.equal(book.booklist.length, 0);
|
|
51
|
-
done();
|
|
52
|
-
},
|
|
53
|
-
);
|
|
19
|
+
it("Use empty book title", { timeout: 20000 }, () => {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
lib.search(
|
|
22
|
+
{
|
|
23
|
+
title: "",
|
|
24
|
+
libraryName: firstLibraryName,
|
|
25
|
+
startPage: 1,
|
|
26
|
+
},
|
|
27
|
+
(err) => {
|
|
28
|
+
if (err) {
|
|
29
|
+
assert.ok(err.msg === "Need a book name");
|
|
30
|
+
} else {
|
|
31
|
+
assert.fail("Need a error msg");
|
|
32
|
+
}
|
|
33
|
+
resolve();
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
});
|
|
54
37
|
});
|
|
55
38
|
|
|
56
|
-
it("Use
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
39
|
+
it("Use invalid book title", { timeout: 20000 }, () => {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
lib.search(
|
|
42
|
+
{
|
|
43
|
+
title: "zyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyz",
|
|
44
|
+
libraryName: firstLibraryName,
|
|
45
|
+
startPage: 1,
|
|
46
|
+
},
|
|
47
|
+
(err, book) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
assert.fail("must have an empty booklist");
|
|
50
|
+
}
|
|
51
|
+
assert.equal(book.booklist.length, 0);
|
|
52
|
+
resolve();
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
});
|
|
71
56
|
});
|
|
72
57
|
|
|
73
|
-
it("
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (book.booklist.length > 0) {
|
|
85
|
-
// util.printBookList(book.booklist);
|
|
86
|
-
util.printTotalBookCount(book);
|
|
87
|
-
} else {
|
|
88
|
-
assert.fail("Book count must be above 1");
|
|
58
|
+
it("Use empty library name", { timeout: 20000 }, () => {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
lib.search(
|
|
61
|
+
{
|
|
62
|
+
title: "javascript",
|
|
63
|
+
libraryName: "",
|
|
64
|
+
startPage: 1,
|
|
65
|
+
},
|
|
66
|
+
(err, book) => {
|
|
67
|
+
if (err) {
|
|
68
|
+
assert.ok(err.msg === "Need a library name");
|
|
89
69
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
assert.equal(book, undefined);
|
|
71
|
+
resolve();
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
});
|
|
94
75
|
});
|
|
95
76
|
|
|
96
|
-
it("
|
|
97
|
-
|
|
98
|
-
let completed = 0;
|
|
99
|
-
const failures = [];
|
|
100
|
-
let successCount = 0;
|
|
101
|
-
|
|
102
|
-
libraryNames.forEach(function (libraryName) {
|
|
77
|
+
it("Show the book list of a library", { timeout: 20000 }, () => {
|
|
78
|
+
return new Promise((resolve) => {
|
|
103
79
|
lib.search(
|
|
104
80
|
{
|
|
105
81
|
title: "javascript",
|
|
106
|
-
libraryName:
|
|
82
|
+
libraryName: firstLibraryName,
|
|
107
83
|
startPage: 1,
|
|
108
84
|
},
|
|
109
|
-
|
|
110
|
-
completed++;
|
|
111
|
-
|
|
85
|
+
(err, book) => {
|
|
112
86
|
if (err) {
|
|
113
|
-
|
|
114
|
-
failures.push(libraryName);
|
|
87
|
+
assert.fail(err.msg);
|
|
115
88
|
} else {
|
|
116
|
-
|
|
117
|
-
book
|
|
118
|
-
`${libraryName} should return a booklist`,
|
|
119
|
-
);
|
|
120
|
-
if (book.totalBookCount > 0) {
|
|
121
|
-
console.log(
|
|
122
|
-
` ✓ ${libraryName}: ${book.totalBookCount} books found`,
|
|
123
|
-
);
|
|
124
|
-
successCount++;
|
|
89
|
+
if (book.booklist.length > 0) {
|
|
90
|
+
util.printTotalBookCount(book);
|
|
125
91
|
} else {
|
|
126
|
-
|
|
127
|
-
console.log(
|
|
128
|
-
` - ${libraryName}: 0 books found (may be expected for small collections)`,
|
|
129
|
-
);
|
|
92
|
+
assert.fail("Book count must be above 1");
|
|
130
93
|
}
|
|
131
94
|
}
|
|
95
|
+
resolve();
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
132
100
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
145
|
-
done();
|
|
146
|
-
}
|
|
101
|
+
it("Verify bookUrl format is valid", { timeout: 30000 }, async () => {
|
|
102
|
+
const book = await new Promise((resolve, reject) => {
|
|
103
|
+
lib.search(
|
|
104
|
+
{
|
|
105
|
+
title: "javascript",
|
|
106
|
+
libraryName: firstLibraryName,
|
|
107
|
+
startPage: 1,
|
|
108
|
+
},
|
|
109
|
+
(err, result) => {
|
|
110
|
+
if (err) reject(new Error(err.msg));
|
|
111
|
+
else resolve(result);
|
|
147
112
|
},
|
|
148
113
|
);
|
|
149
114
|
});
|
|
115
|
+
|
|
116
|
+
assert.ok(book.booklist.length > 0, "Need at least one book to test bookUrl");
|
|
117
|
+
|
|
118
|
+
const bookWithUrl = book.booklist.find((b) => b.bookUrl);
|
|
119
|
+
assert.ok(bookWithUrl, "At least one book should have a bookUrl");
|
|
120
|
+
|
|
121
|
+
const bookUrl = bookWithUrl.bookUrl;
|
|
122
|
+
|
|
123
|
+
assert.ok(
|
|
124
|
+
bookUrl.startsWith("http://") || bookUrl.startsWith("https://"),
|
|
125
|
+
`bookUrl should start with http:// or https://: ${bookUrl}`,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const getBaseDomain = (url) => {
|
|
129
|
+
try {
|
|
130
|
+
const hostname = new URL(url.split("#")[0]).hostname;
|
|
131
|
+
const parts = hostname.split(".");
|
|
132
|
+
return parts.slice(-2).join(".");
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const homeBaseDomain = getBaseDomain(lib.homeUrl);
|
|
139
|
+
const bookBaseDomain = getBaseDomain(bookUrl);
|
|
140
|
+
|
|
141
|
+
assert.ok(
|
|
142
|
+
homeBaseDomain && bookBaseDomain && homeBaseDomain === bookBaseDomain,
|
|
143
|
+
`bookUrl domain (${bookBaseDomain}) should match homeUrl domain (${homeBaseDomain}): ${bookUrl}`,
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const urlWithoutHash = bookUrl.split("#")[0];
|
|
147
|
+
try {
|
|
148
|
+
new URL(urlWithoutHash);
|
|
149
|
+
} catch {
|
|
150
|
+
assert.fail(`bookUrl base is not a valid URL: ${bookUrl}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(` ✓ bookUrl format verified: ${bookUrl}`);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("Make sure the book is searchable in each library", { timeout: 60000 }, () => {
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
let completed = 0;
|
|
159
|
+
const failures = [];
|
|
160
|
+
let successCount = 0;
|
|
161
|
+
|
|
162
|
+
libraryNames.forEach((libraryName) => {
|
|
163
|
+
lib.search(
|
|
164
|
+
{
|
|
165
|
+
title: "javascript",
|
|
166
|
+
libraryName: libraryName,
|
|
167
|
+
startPage: 1,
|
|
168
|
+
},
|
|
169
|
+
(err, book) => {
|
|
170
|
+
completed++;
|
|
171
|
+
|
|
172
|
+
if (err) {
|
|
173
|
+
console.log(` ✗ ${libraryName}: ${err.msg}`);
|
|
174
|
+
failures.push(libraryName);
|
|
175
|
+
} else {
|
|
176
|
+
assert.ok(
|
|
177
|
+
book.booklist !== undefined,
|
|
178
|
+
`${libraryName} should return a booklist`,
|
|
179
|
+
);
|
|
180
|
+
if (book.totalBookCount > 0) {
|
|
181
|
+
console.log(
|
|
182
|
+
` ✓ ${libraryName}: ${book.totalBookCount} books found`,
|
|
183
|
+
);
|
|
184
|
+
successCount++;
|
|
185
|
+
} else {
|
|
186
|
+
console.log(
|
|
187
|
+
` - ${libraryName}: 0 books found (may be expected for small collections)`,
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (completed === libraryNames.length) {
|
|
193
|
+
console.log(
|
|
194
|
+
` Summary: ${successCount} libraries with results, ${failures.length} errors`,
|
|
195
|
+
);
|
|
196
|
+
assert.ok(
|
|
197
|
+
failures.length < libraryNames.length,
|
|
198
|
+
"At least one library should be searchable",
|
|
199
|
+
);
|
|
200
|
+
assert.ok(
|
|
201
|
+
successCount > 0,
|
|
202
|
+
"At least one library should return results",
|
|
203
|
+
);
|
|
204
|
+
resolve();
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
150
210
|
});
|
|
151
211
|
});
|
|
152
212
|
}
|
package/test/util.spec.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
const { describe, it } = require("node:test");
|
|
1
2
|
const util = require("../src/util");
|
|
2
3
|
const assert = require("assert");
|
|
3
4
|
|
|
4
|
-
describe("util",
|
|
5
|
-
describe("콤마로 구분된 여러 도서관 이름 분리",
|
|
6
|
-
it("should return second item of testArray",
|
|
5
|
+
describe("util", () => {
|
|
6
|
+
describe("콤마로 구분된 여러 도서관 이름 분리", () => {
|
|
7
|
+
it("should return second item of testArray", () => {
|
|
7
8
|
const testArray = ["apple", "banana", "meleon"];
|
|
8
9
|
assert.equal(
|
|
9
10
|
testArray[1],
|