@natlibfi/marc-record-validators-melinda 9.0.4 → 9.0.5-alpha.1

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/dist/isbn-issn.js CHANGED
@@ -17,7 +17,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
17
17
  *
18
18
  * MARC record validators used in Melinda
19
19
  *
20
- * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)
20
+ * Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)
21
21
  *
22
22
  * This file is part of marc-record-validators-melinda
23
23
  *
@@ -38,6 +38,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
38
38
  * for the JavaScript code in this file.
39
39
  *
40
40
  */
41
+ // handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y
41
42
  var _default = ({
42
43
  hyphenateISBN = false,
43
44
  handleInvalid = false
@@ -48,62 +49,118 @@ var _default = ({
48
49
  description: 'Validates ISBN and ISSN values'
49
50
  };
50
51
 
51
- function getInvalidFields(record) {
52
- return record.get(/^(020|022)$/u).filter(field => {
53
- // eslint-disable-line prefer-named-capture-group
54
- // Check ISBN:
55
- if (field.tag === '020') {
56
- if (invalidField020(field)) {
57
- return true;
58
- }
59
-
60
- const subfield = field.subfields.find(sf => sf.code === 'a');
52
+ function invalidISBN(isbn) {
53
+ // If value contains space, it's not necessarily crap. (It's typically something like "1234567890 (nid.)".)
54
+ // Check the first word in string:
55
+ if (isbn.indexOf(' ') > -1) {
56
+ // const arr = isbn.split(' ');
57
+ // console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
58
+ // return invalidISBN(arr[0]);
59
+ return true;
60
+ }
61
61
 
62
- const auditedIsbn = _isbn.default.audit(subfield.value);
62
+ const auditedIsbn = _isbn.default.audit(isbn);
63
63
 
64
- if (!auditedIsbn.validIsbn) {
65
- return true;
66
- } // Should we refactor code by adding a function that returns legal set of values,
67
- // and then we compare subfield.value against that list?
64
+ if (!auditedIsbn.validIsbn) {
65
+ console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console
68
66
 
67
+ return true;
68
+ }
69
69
 
70
- const parsedIsbn = _isbn.default.parse(subfield.value);
70
+ return false;
71
+ }
71
72
 
72
- if (hyphenateISBN) {
73
- return !(subfield.value === parsedIsbn.isbn10h || subfield.value === parsedIsbn.isbn13h);
74
- }
73
+ function invalidField020(field) {
74
+ if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {
75
+ return true;
76
+ }
75
77
 
76
- return !(subfield.value === parsedIsbn.isbn10 || subfield.value === parsedIsbn.isbn13);
77
- } // Check ISSN:
78
+ return false;
78
79
 
80
+ function invalidField020a(subfield) {
81
+ if (subfield.code !== 'a') {
82
+ return false;
83
+ }
79
84
 
80
- if (invalidField022(field)) {
85
+ if (invalidISBN(subfield.value)) {
81
86
  return true;
82
87
  }
83
88
 
84
- const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
85
- return !(0, _issnVerify.default)(subfield.value);
86
- });
89
+ return false;
90
+ }
87
91
 
88
- function invalidField020(field) {
89
- const subfieldA = field.subfields.find(sf => sf.code === 'a');
92
+ function invalidField020z(subfield) {
93
+ if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {
94
+ return false;
95
+ } // We are only interested in $z field if it is valid ISBN that requires hyphenation:
90
96
 
91
- if (subfieldA === undefined) {
92
- const subfieldZ = field.subfields.find(sf => sf.code === 'z');
93
97
 
94
- if (subfieldZ !== undefined) {
95
- return false;
98
+ return subfield.value.indexOf('-') === -1;
99
+ }
100
+ }
101
+
102
+ function subfieldRequiresHyphenation(subfield) {
103
+ if (subfield.code !== 'a' && subfield.code !== 'z') {
104
+ return false;
105
+ }
106
+
107
+ return requiresHyphenation(subfield.value);
108
+
109
+ function requiresHyphenation(isbn) {
110
+ if (isbn.indexOf(' ') > -1) {
111
+ const arr = isbn.split(' ');
112
+ console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
113
+
114
+ return requiresHyphenation(arr[0]);
115
+ }
116
+
117
+ if (invalidISBN(isbn)) {
118
+ return false;
119
+ }
120
+
121
+ console.info(`sfRH ${isbn}`); // eslint-disable-line no-console
122
+
123
+ const parsedIsbn = _isbn.default.parse(isbn);
124
+
125
+ if (hyphenateISBN) {
126
+ return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);
127
+ }
128
+
129
+ return false; //return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);
130
+ }
131
+ }
132
+
133
+ function getInvalidFields(record) {
134
+ //return record.get(/^(?:020|022)$/u).filter(field => {
135
+ return record.fields.filter(field => {
136
+ if (!field.subfields) {
137
+ return false;
138
+ } // Check ISBN:
139
+
140
+
141
+ if (field.tag === '020') {
142
+ if (invalidField020(field)) {
143
+ return true;
96
144
  }
97
145
 
98
- return true;
99
- } // If value contains space, it's not ok (it's typically something like "1234567890 (nid.)")
146
+ return fieldRequiresHyphenation(field);
147
+ } // Check ISSN:
100
148
 
101
149
 
102
- if (subfieldA.value.indexOf(' ') > -1) {
103
- return true;
150
+ if (field.tag === '022') {
151
+ if (invalidField022(field)) {
152
+ return true;
153
+ }
154
+
155
+ const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
156
+ return !(0, _issnVerify.default)(subfield.value);
104
157
  }
105
158
 
106
159
  return false;
160
+ });
161
+
162
+ function fieldRequiresHyphenation(field) {
163
+ return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));
107
164
  }
108
165
 
109
166
  function invalidField022(field) {
@@ -181,66 +238,86 @@ var _default = ({
181
238
  function fix(record) {
182
239
  getInvalidFields(record).forEach(field => {
183
240
  if (field.tag === '020') {
184
- const subfield = field.subfields.find(sf => sf.code === 'a');
241
+ field.subfields.forEach(subfield => fixField020Subfield(field, subfield));
242
+ return;
243
+ } // 022 ISSN:
185
244
 
186
- if (subfield) {
187
- // ISBN is valid but is missing hyphens
188
- const normalizedValue = normalizeIsbnValue(subfield.value);
189
245
 
190
- if (normalizedValue !== undefined) {
191
- // eslint-disable-line functional/no-conditional-statement
192
- subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
193
- } else if (handleInvalid) {
194
- // eslint-disable-line functional/no-conditional-statement
195
- field.subfields.push({
196
- code: 'z',
197
- value: subfield.value
198
- }); // eslint-disable-line functional/immutable-data
246
+ const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
199
247
 
200
- record.removeSubfield(subfield, field);
201
- }
202
- }
203
- } else {
204
- const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
248
+ if (subfield && handleInvalid) {
249
+ // eslint-disable-line functional/no-conditional-statement
250
+ // $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)
251
+ field.subfields.push({
252
+ code: 'y',
253
+ value: subfield.value
254
+ }); // eslint-disable-line functional/immutable-data
205
255
 
206
- if (subfield && handleInvalid) {
256
+ record.removeSubfield(subfield, field);
257
+ }
258
+ });
259
+ /*
260
+ function trimISBN(value) {
261
+ return trimSpaces(value.replace(/\s$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
262
+ }
263
+ */
264
+
265
+ function fixField020Subfield(field, subfield) {
266
+ console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
267
+
268
+ if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {
269
+ console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
270
+ // ISBN is valid but is missing hyphens
271
+
272
+ const normalizedValue = normalizeIsbnValue(subfield.value);
273
+
274
+ if (normalizedValue !== undefined) {
275
+ // eslint-disable-line functional/no-conditional-statement
276
+ subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
277
+ } else if (subfield.code === 'a' && handleInvalid) {
207
278
  // eslint-disable-line functional/no-conditional-statement
279
+ // $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)
208
280
  field.subfields.push({
209
- code: 'y',
210
- value: trimSpaces(subfield.value)
281
+ code: 'z',
282
+ value: subfield.value
211
283
  }); // eslint-disable-line functional/immutable-data
212
284
 
213
285
  record.removeSubfield(subfield, field);
214
286
  }
215
287
  }
216
- });
217
288
 
218
- function normalizeIsbnValue(value) {
219
- const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
289
+ return;
220
290
 
221
- const auditResult = _isbn.default.audit(trimmedValue);
291
+ function normalizeIsbnValue2(trimmedValue) {
292
+ //const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
293
+ const auditResult = _isbn.default.audit(trimmedValue);
222
294
 
223
- if (auditResult.validIsbn) {
224
- const parsedIsbn = _isbn.default.parse(trimmedValue);
295
+ if (auditResult.validIsbn) {
296
+ const parsedIsbn = _isbn.default.parse(trimmedValue);
225
297
 
226
- if (hyphenateISBN) {
227
- // eslint-disable-line functional/no-conditional-statement
228
- return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
229
- } // Just trim
298
+ if (hyphenateISBN) {
299
+ // eslint-disable-line functional/no-conditional-statement
300
+ return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
301
+ } // Just trim
230
302
 
231
303
 
232
- return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
304
+ return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
305
+ }
306
+
307
+ return undefined;
233
308
  }
234
309
 
235
- return undefined;
236
- }
310
+ function normalizeIsbnValue(value) {
311
+ const trimmedValue = value.replace(/^\s+/gu, '');
237
312
 
238
- function trimSpaces(value) {
239
- return value.replace(/\s/gu, '');
240
- }
313
+ if (trimmedValue.indexOf(' ') === -1) {
314
+ return normalizeIsbnValue2(trimmedValue);
315
+ }
241
316
 
242
- function trimISBN(value) {
243
- return trimSpaces(value.replace(/\s\D+$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
317
+ const [head] = trimmedValue.split(' '); // NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?
318
+
319
+ return normalizeIsbnValue2(head);
320
+ }
244
321
  }
245
322
  }
246
323
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/isbn-issn.js"],"names":["hyphenateISBN","handleInvalid","validate","fix","description","getInvalidFields","record","get","filter","field","tag","invalidField020","subfield","subfields","find","sf","code","auditedIsbn","ISBN","audit","value","validIsbn","parsedIsbn","parse","isbn10h","isbn13h","isbn10","isbn13","invalidField022","subfieldA","undefined","subfieldZ","indexOf","subfieldAorL","subfieldY","fields","length","valid","map","name","getISSN","reduce","acc","obj","msg","messages","concat","forEach","normalizedValue","normalizeIsbnValue","push","removeSubfield","trimSpaces","trimmedValue","trimISBN","auditResult","replace"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* MARC record validators used in Melinda\n*\n* Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of marc-record-validators-melinda\n*\n* marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Lesser General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* marc-record-validators-melinda is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport ISBN from 'isbn3';\nimport validateISSN from '@natlibfi/issn-verify';\n\nexport default ({hyphenateISBN = false, handleInvalid = false} = {}) => {\n return {\n validate, fix,\n description: 'Validates ISBN and ISSN values'\n };\n\n function getInvalidFields(record) {\n return record.get(/^(020|022)$/u).filter(field => { // eslint-disable-line prefer-named-capture-group\n // Check ISBN:\n if (field.tag === '020') {\n if (invalidField020(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a');\n const auditedIsbn = ISBN.audit(subfield.value);\n if (!auditedIsbn.validIsbn) {\n return true;\n }\n // Should we refactor code by adding a function that returns legal set of values,\n // and then we compare subfield.value against that list?\n const parsedIsbn = ISBN.parse(subfield.value);\n if (hyphenateISBN) {\n return !(subfield.value === parsedIsbn.isbn10h || subfield.value === parsedIsbn.isbn13h);\n }\n\n return !(subfield.value === parsedIsbn.isbn10 || subfield.value === parsedIsbn.isbn13);\n }\n // Check ISSN:\n if (invalidField022(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n return !validateISSN(subfield.value);\n });\n\n function invalidField020(field) {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n\n if (subfieldA === undefined) {\n const subfieldZ = field.subfields.find(sf => sf.code === 'z');\n if (subfieldZ !== undefined) {\n return false;\n }\n return true;\n }\n\n // If value contains space, it's not ok (it's typically something like \"1234567890 (nid.)\")\n if (subfieldA.value.indexOf(' ') > -1) {\n return true;\n }\n return false;\n }\n\n function invalidField022(field) {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL === undefined) {\n const subfieldY = field.subfields.find(sf => sf.code === 'y');\n if (subfieldY) {\n return false;\n }\n\n return true;\n }\n return false;\n }\n }\n\n function validate(record) {\n const fields = getInvalidFields(record);\n\n if (fields.length === 0) {\n return {valid: true};\n }\n\n return fields\n .map(field => {\n if (field.tag === '020') {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (subfieldA) {\n return {name: 'ISBN', value: subfieldA.value};\n }\n\n return {name: 'ISBN', value: undefined};\n }\n\n return {name: 'ISSN', value: getISSN()};\n\n function getISSN() {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL) {\n return subfieldAorL.value;\n }\n\n return undefined;\n }\n })\n .reduce((acc, obj) => {\n const {name, value} = obj;\n const msg = `${name} (${value}) is not valid`;\n\n return {...acc, messages: acc.messages.concat(msg)};\n }, {valid: false, messages: []});\n }\n\n function fix(record) {\n getInvalidFields(record).forEach(field => {\n if (field.tag === '020') {\n const subfield = field.subfields.find(sf => sf.code === 'a');\n if (subfield) {\n // ISBN is valid but is missing hyphens\n const normalizedValue = normalizeIsbnValue(subfield.value);\n if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement\n subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data\n } else if (handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n } else {\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n field.subfields.push({code: 'y', value: trimSpaces(subfield.value)}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n });\n\n function normalizeIsbnValue(value) {\n const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...\n const auditResult = ISBN.audit(trimmedValue);\n if (auditResult.validIsbn) {\n const parsedIsbn = ISBN.parse(trimmedValue);\n if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement\n return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data\n }\n // Just trim\n return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data\n }\n return undefined;\n }\n\n function trimSpaces(value) {\n return value.replace(/\\s/gu, '');\n }\n\n function trimISBN(value) {\n return trimSpaces(value.replace(/\\s\\D+$/gu, '')); // handle \"1234567890 (nid.)\" => \"1234567890\" as well as spaces\n }\n }\n};\n"],"file":"isbn-issn.js"}
1
+ {"version":3,"sources":["../src/isbn-issn.js"],"names":["hyphenateISBN","handleInvalid","validate","fix","description","invalidISBN","isbn","indexOf","auditedIsbn","ISBN","audit","validIsbn","console","info","invalidField020","field","subfields","some","sf","invalidField020a","invalidField020z","subfield","code","value","subfieldRequiresHyphenation","requiresHyphenation","arr","split","parsedIsbn","parse","isbn10h","isbn13h","getInvalidFields","record","fields","filter","tag","fieldRequiresHyphenation","invalidField022","find","subfieldAorL","undefined","subfieldY","length","valid","map","subfieldA","name","getISSN","reduce","acc","obj","msg","messages","concat","forEach","fixField020Subfield","push","removeSubfield","normalizedValue","normalizeIsbnValue","normalizeIsbnValue2","trimmedValue","auditResult","isbn10","isbn13","replace","head"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* MARC record validators used in Melinda\n*\n* Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of marc-record-validators-melinda\n*\n* marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Lesser General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* marc-record-validators-melinda is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport ISBN from 'isbn3';\nimport validateISSN from '@natlibfi/issn-verify';\n\n// handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y\nexport default ({hyphenateISBN = false, handleInvalid = false} = {}) => {\n return {\n validate, fix,\n description: 'Validates ISBN and ISSN values'\n };\n\n function invalidISBN(isbn) {\n // If value contains space, it's not necessarily crap. (It's typically something like \"1234567890 (nid.)\".)\n // Check the first word in string:\n if (isbn.indexOf(' ') > -1) {\n // const arr = isbn.split(' ');\n // console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console\n // return invalidISBN(arr[0]);\n return true;\n }\n\n const auditedIsbn = ISBN.audit(isbn);\n if (!auditedIsbn.validIsbn) {\n console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console\n return true;\n }\n return false;\n }\n\n\n function invalidField020(field) {\n if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {\n return true;\n }\n return false;\n\n function invalidField020a(subfield) {\n if (subfield.code !== 'a') {\n return false;\n }\n if (invalidISBN(subfield.value)) {\n return true;\n }\n return false;\n }\n\n function invalidField020z(subfield) {\n if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {\n return false;\n }\n // We are only interested in $z field if it is valid ISBN that requires hyphenation:\n return subfield.value.indexOf('-') === -1;\n }\n }\n\n function subfieldRequiresHyphenation(subfield) {\n if (subfield.code !== 'a' && subfield.code !== 'z') {\n return false;\n }\n return requiresHyphenation(subfield.value);\n\n function requiresHyphenation(isbn) {\n if (isbn.indexOf(' ') > -1) {\n const arr = isbn.split(' ');\n console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console\n return requiresHyphenation(arr[0]);\n }\n\n if (invalidISBN(isbn)) {\n return false;\n }\n console.info(`sfRH ${isbn}`); // eslint-disable-line no-console\n const parsedIsbn = ISBN.parse(isbn);\n if (hyphenateISBN) {\n return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);\n }\n return false;\n //return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);\n }\n }\n\n function getInvalidFields(record) {\n //return record.get(/^(?:020|022)$/u).filter(field => {\n return record.fields.filter(field => {\n if (!field.subfields) {\n return false;\n }\n // Check ISBN:\n if (field.tag === '020') {\n if (invalidField020(field)) {\n return true;\n }\n return fieldRequiresHyphenation(field);\n }\n\n // Check ISSN:\n if (field.tag === '022') {\n if (invalidField022(field)) {\n return true;\n }\n\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n return !validateISSN(subfield.value);\n }\n return false;\n });\n\n function fieldRequiresHyphenation(field) {\n return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));\n }\n\n function invalidField022(field) {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL === undefined) {\n const subfieldY = field.subfields.find(sf => sf.code === 'y');\n if (subfieldY) {\n return false;\n }\n\n return true;\n }\n return false;\n }\n }\n\n function validate(record) {\n const fields = getInvalidFields(record);\n\n if (fields.length === 0) {\n return {valid: true};\n }\n\n return fields\n .map(field => {\n if (field.tag === '020') {\n const subfieldA = field.subfields.find(sf => sf.code === 'a');\n if (subfieldA) {\n return {name: 'ISBN', value: subfieldA.value};\n }\n\n return {name: 'ISBN', value: undefined};\n }\n\n return {name: 'ISSN', value: getISSN()};\n\n function getISSN() {\n const subfieldAorL = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n\n if (subfieldAorL) {\n return subfieldAorL.value;\n }\n\n return undefined;\n }\n })\n .reduce((acc, obj) => {\n const {name, value} = obj;\n const msg = `${name} (${value}) is not valid`;\n\n return {...acc, messages: acc.messages.concat(msg)};\n }, {valid: false, messages: []});\n }\n\n\n function fix(record) {\n getInvalidFields(record).forEach(field => {\n if (field.tag === '020') {\n field.subfields.forEach(subfield => fixField020Subfield(field, subfield));\n return;\n }\n // 022 ISSN:\n const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');\n if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n // $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)\n field.subfields.push({code: 'y', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n });\n\n /*\n function trimISBN(value) {\n return trimSpaces(value.replace(/\\s$/gu, '')); // handle \"1234567890 (nid.)\" => \"1234567890\" as well as spaces\n }\n */\n\n function fixField020Subfield(field, subfield) {\n console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console\n if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {\n console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console\n // ISBN is valid but is missing hyphens\n const normalizedValue = normalizeIsbnValue(subfield.value);\n if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement\n subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data\n } else if (subfield.code === 'a' && handleInvalid) { // eslint-disable-line functional/no-conditional-statement\n // $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)\n field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data\n record.removeSubfield(subfield, field);\n }\n }\n return;\n\n function normalizeIsbnValue2(trimmedValue) {\n //const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...\n const auditResult = ISBN.audit(trimmedValue);\n if (auditResult.validIsbn) {\n const parsedIsbn = ISBN.parse(trimmedValue);\n if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement\n return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data\n }\n // Just trim\n return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data\n }\n return undefined;\n }\n\n function normalizeIsbnValue(value) {\n const trimmedValue = value.replace(/^\\s+/gu, '');\n if (trimmedValue.indexOf(' ') === -1) {\n return normalizeIsbnValue2(trimmedValue);\n }\n const [head] = trimmedValue.split(' ');\n // NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?\n return normalizeIsbnValue2(head);\n }\n }\n }\n};\n"],"file":"isbn-issn.js"}
@@ -64,6 +64,14 @@ describe('isbn-issn', () => {
64
64
  code: 'a',
65
65
  value: '90-6831-372-X'
66
66
  }]
67
+ }, {
68
+ tag: '020',
69
+ ind1: ' ',
70
+ ind2: ' ',
71
+ subfields: [{
72
+ code: 'z',
73
+ value: '978-600-377-017-1'
74
+ }]
67
75
  }, {
68
76
  tag: '022',
69
77
  ind1: ' ',
@@ -106,7 +114,7 @@ describe('isbn-issn', () => {
106
114
  messages: ['ISBN (foo) is not valid', 'ISSN (bar) is not valid']
107
115
  });
108
116
  });
109
- it('Finds the invalid 020 field', async () => {
117
+ it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {
110
118
  const validator = await (0, _isbnIssn.default)();
111
119
  const record = new _marcRecord.MarcRecord({
112
120
  fields: [{
@@ -121,8 +129,7 @@ describe('isbn-issn', () => {
121
129
  });
122
130
  const result = await validator.validate(record);
123
131
  (0, _chai.expect)(result).to.eql({
124
- valid: false,
125
- messages: ['ISBN (undefined) is not valid']
132
+ valid: true
126
133
  });
127
134
  });
128
135
  it('Finds the invalid 022 field', async () => {
@@ -252,6 +259,23 @@ describe('isbn-issn', () => {
252
259
  code: 'a',
253
260
  value: 'crappy val'
254
261
  }]
262
+ }, {
263
+ tag: '020',
264
+ ind1: ' ',
265
+ ind2: ' ',
266
+ subfields: [{
267
+ code: 'a',
268
+ value: '97895234216609'
269
+ }]
270
+ }, // Just a sanity check due to earlier issues:
271
+ {
272
+ tag: '020',
273
+ ind1: ' ',
274
+ ind2: ' ',
275
+ subfields: [{
276
+ code: 'z',
277
+ value: '97895234216609'
278
+ }]
255
279
  }]
256
280
  });
257
281
  await validator.fix(record);
@@ -271,6 +295,22 @@ describe('isbn-issn', () => {
271
295
  code: 'z',
272
296
  value: 'crappy val'
273
297
  }]
298
+ }, {
299
+ tag: '020',
300
+ ind1: ' ',
301
+ ind2: ' ',
302
+ subfields: [{
303
+ code: 'z',
304
+ value: '97895234216609'
305
+ }]
306
+ }, {
307
+ tag: '020',
308
+ ind1: ' ',
309
+ ind2: ' ',
310
+ subfields: [{
311
+ code: 'z',
312
+ value: '97895234216609'
313
+ }]
274
314
  }]);
275
315
  });
276
316
  it('Moves invalid ISSN to y-subfield', async () => {
@@ -376,7 +416,13 @@ describe('isbn-issn', () => {
376
416
  ind2: ' ',
377
417
  subfields: [{
378
418
  code: 'a',
379
- value: ' 9786003770171'
419
+ value: '9786003770171 (nid.)'
420
+ }, {
421
+ code: 'z',
422
+ value: '9786003770171 (nid.)'
423
+ }, {
424
+ code: 'z',
425
+ value: 'foo bar'
380
426
  }]
381
427
  }]
382
428
  });
@@ -388,10 +434,48 @@ describe('isbn-issn', () => {
388
434
  subfields: [{
389
435
  code: 'a',
390
436
  value: '978-600-377-017-1'
437
+ }, {
438
+ code: 'z',
439
+ value: '978-600-377-017-1'
440
+ }, {
441
+ code: 'z',
442
+ value: 'foo bar'
443
+ }]
444
+ }]);
445
+ });
446
+ it('No relevant data', async () => {
447
+ const validator = await (0, _isbnIssn.default)({
448
+ hyphenateISBN: true
449
+ });
450
+ const record = new _marcRecord.MarcRecord({
451
+ fields: [{
452
+ tag: '005',
453
+ value: 'whatever'
454
+ }, {
455
+ tag: '024',
456
+ ind1: ' ',
457
+ ind2: ' ',
458
+ subfields: [{
459
+ code: 'a',
460
+ value: ' 9786003770171'
461
+ }]
462
+ }]
463
+ });
464
+ await validator.fix(record);
465
+ (0, _chai.expect)(record.fields).to.eql([{
466
+ tag: '005',
467
+ value: 'whatever'
468
+ }, {
469
+ tag: '024',
470
+ ind1: ' ',
471
+ ind2: ' ',
472
+ subfields: [{
473
+ code: 'a',
474
+ value: ' 9786003770171'
391
475
  }]
392
476
  }]);
393
477
  });
394
- it('Adds hyphens to ISBN', async () => {
478
+ it('Add hyphens to ISBN', async () => {
395
479
  const validator = await (0, _isbnIssn.default)({
396
480
  hyphenateISBN: true
397
481
  });
@@ -420,6 +504,22 @@ describe('isbn-issn', () => {
420
504
  code: 'a',
421
505
  value: '386006004X (nid.)'
422
506
  }]
507
+ }, {
508
+ tag: '020',
509
+ ind1: ' ',
510
+ ind2: ' ',
511
+ subfields: [{
512
+ code: 'z',
513
+ value: '9789916605325'
514
+ }]
515
+ }, {
516
+ tag: '020',
517
+ ind1: ' ',
518
+ ind2: ' ',
519
+ subfields: [{
520
+ code: 'z',
521
+ value: '9789916605325 (sid.)'
522
+ }]
423
523
  }]
424
524
  });
425
525
  await validator.fix(record);
@@ -447,6 +547,22 @@ describe('isbn-issn', () => {
447
547
  code: 'a',
448
548
  value: '3-86006-004-X'
449
549
  }]
550
+ }, {
551
+ tag: '020',
552
+ ind1: ' ',
553
+ ind2: ' ',
554
+ subfields: [{
555
+ code: 'z',
556
+ value: '978-9916-605-32-5'
557
+ }]
558
+ }, {
559
+ tag: '020',
560
+ ind1: ' ',
561
+ ind2: ' ',
562
+ subfields: [{
563
+ code: 'z',
564
+ value: '978-9916-605-32-5'
565
+ }]
450
566
  }]);
451
567
  });
452
568
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/isbn-issn.spec.js"],"names":["describe","it","validator","to","be","an","that","has","any","keys","description","a","validate","hyphenateISBN","record","MarcRecord","fields","tag","ind1","ind2","subfields","code","value","result","eql","valid","messages","skip","handleInvalid","fix"],"mappings":"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","sourcesContent":["/**\n *\n * @licstart The following is the entire license notice for the JavaScript code in this file.\n *\n * MARC record validators used in Melinda\n *\n * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n *\n * This file is part of marc-record-validators-melinda\n *\n * marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * marc-record-validators-melinda is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n * @licend The above is the entire license notice\n * for the JavaScript code in this file.\n *\n */\n\n\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from '../src/isbn-issn';\n\ndescribe('isbn-issn', () => {\n it('Creates a validator', async () => {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('function');\n });\n\n describe('#validate', () => {\n it('Finds the record valid', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '90-6831-372-X'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '0355-0893'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: true});\n });\n\n it('Finds the record invalid', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the invalid 020 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'q', value: 'nidottu'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISBN (undefined) is not valid']\n });\n });\n\n it('Finds the invalid 022 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'z', value: '0000-0000'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISSN (undefined) is not valid']\n });\n });\n\n it('Finds the record invalid (Spaces in ISBN)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1 (nid.)'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN ( 9789519155470) is not valid',\n 'ISBN (978-600-377-017-1 (nid.)) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (ISSN in \\'l\\'-subfield)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'l', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (valid ISBN without hyphens)', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '386006004X'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: false, messages: [\n 'ISBN (9789519155470) is not valid',\n 'ISBN (386006004X) is not valid'\n ]});\n });\n\n it.skip('Finds the record invalid (Missing ISBN)');\n it.skip('Finds the record invalid (Missing ISSN)');\n });\n\n describe('#fix', () => {\n it('Moves invalid ISBN to z-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'crappy val'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]}\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield (Origin l-subfield)', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'l', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Trims spaces from value (No hyphenate)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9786003770171 (nid.)'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]}\n ]);\n });\n\n it('Trims spaces and hyphenates value', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-600-377-017-1'}]\n }\n ]);\n });\n\n it('Adds hyphens to ISBN', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '9789916605325'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '917153086X'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '386006004X (nid.)'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]}\n ]);\n });\n });\n});\n"],"file":"isbn-issn.spec.js"}
1
+ {"version":3,"sources":["../src/isbn-issn.spec.js"],"names":["describe","it","validator","to","be","an","that","has","any","keys","description","a","validate","hyphenateISBN","record","MarcRecord","fields","tag","ind1","ind2","subfields","code","value","result","eql","valid","messages","skip","handleInvalid","fix"],"mappings":"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","sourcesContent":["/**\n *\n * @licstart The following is the entire license notice for the JavaScript code in this file.\n *\n * MARC record validators used in Melinda\n *\n * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)\n *\n * This file is part of marc-record-validators-melinda\n *\n * marc-record-validators-melinda program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * marc-record-validators-melinda is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n * @licend The above is the entire license notice\n * for the JavaScript code in this file.\n *\n */\n\n\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from '../src/isbn-issn';\n\ndescribe('isbn-issn', () => {\n it('Creates a validator', async () => {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('function');\n });\n\n describe('#validate', () => {\n it('Finds the record valid', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '90-6831-372-X'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-600-377-017-1'}]},\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '0355-0893'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: true});\n });\n\n it('Finds the record invalid', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'q', value: 'nidottu'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: true\n });\n });\n\n it('Finds the invalid 022 field', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'z', value: '0000-0000'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: ['ISSN (undefined) is not valid']\n });\n });\n\n it('Finds the record invalid (Spaces in ISBN)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '978-600-377-017-1 (nid.)'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN ( 9789519155470) is not valid',\n 'ISBN (978-600-377-017-1 (nid.)) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (ISSN in \\'l\\'-subfield)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '022',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'l', value: 'bar'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({\n valid: false, messages: [\n 'ISBN (foo) is not valid',\n 'ISSN (bar) is not valid'\n ]\n });\n });\n\n it('Finds the record invalid (valid ISBN without hyphens)', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9789519155470'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '386006004X'}]\n }\n ]\n });\n const result = await validator.validate(record);\n\n expect(result).to.eql({valid: false, messages: [\n 'ISBN (9789519155470) is not valid',\n 'ISBN (386006004X) is not valid'\n ]});\n });\n\n it.skip('Finds the record invalid (Missing ISBN)');\n it.skip('Finds the record invalid (Missing ISSN)');\n });\n\n describe('#fix', () => {\n it('Moves invalid ISBN to z-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'crappy val'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '97895234216609'}]},\n // Just a sanity check due to earlier issues:\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Moves invalid ISSN to y-subfield (Origin l-subfield)', async () => {\n const validator = await validatorFactory({handleInvalid: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '022', ind1: ' ', ind2: ' ',\n subfields: [{code: 'l', value: 'foo'}]\n }\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '022', ind1: ' ', ind2: ' ', subfields: [{code: 'y', value: 'foo'}]\n }\n ]);\n });\n\n it('Trims spaces from value (No hyphenate)', async () => {\n const validator = await validatorFactory();\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n },\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: '9786003770171 (nid.)'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '9786003770171'}]}\n ]);\n });\n\n it('Trims spaces and hyphenates value', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [\n {code: 'a', value: '9786003770171 (nid.)'},\n {code: 'z', value: '9786003770171 (nid.)'},\n {code: 'z', value: 'foo bar'}\n ]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {\n tag: '020',\n ind1: ' ',\n ind2: ' ',\n subfields: [\n {code: 'a', value: '978-600-377-017-1'},\n {code: 'z', value: '978-600-377-017-1'},\n {code: 'z', value: 'foo bar'}\n ]\n }\n ]);\n });\n\n it('No relevant data', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '005',\n value: 'whatever'\n },\n {\n tag: '024',\n ind1: ' ',\n ind2: ' ',\n subfields: [{code: 'a', value: ' 9786003770171'}]\n }\n ]\n });\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '005', value: 'whatever'},\n {tag: '024', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]}\n ]);\n });\n\n it('Add hyphens to ISBN', async () => {\n const validator = await validatorFactory({hyphenateISBN: true});\n const record = new MarcRecord({\n fields: [\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '9789916605325'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '917153086X'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'a', value: '386006004X (nid.)'}]\n },\n {\n tag: '020', ind1: ' ', ind2: ' ',\n subfields: [{code: 'z', value: '9789916605325'}]\n },\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '9789916605325 (sid.)'}]}\n ]\n });\n\n await validator.fix(record);\n\n expect(record.fields).to.eql([\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]},\n {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]}\n ]);\n });\n });\n});\n"],"file":"isbn-issn.spec.js"}
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "url": "git@github.com:natlibfi/marc-record-validators-melinda.git"
15
15
  },
16
16
  "license": "LGPL-3.0+",
17
- "version": "9.0.4",
17
+ "version": "9.0.5-alpha.1",
18
18
  "main": "./dist/index.js",
19
19
  "publishConfig": {
20
20
  "access": "public"
package/src/isbn-issn.js CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * MARC record validators used in Melinda
6
6
  *
7
- * Copyright (c) 2014-2020 University Of Helsinki (The National Library Of Finland)
7
+ * Copyright (c) 2014-2022 University Of Helsinki (The National Library Of Finland)
8
8
  *
9
9
  * This file is part of marc-record-validators-melinda
10
10
  *
@@ -29,60 +29,112 @@
29
29
  import ISBN from 'isbn3';
30
30
  import validateISSN from '@natlibfi/issn-verify';
31
31
 
32
+ // handleInvalid: move invalid 020$a to 020$z, and invalid 022$a to 022$y
32
33
  export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
33
34
  return {
34
35
  validate, fix,
35
36
  description: 'Validates ISBN and ISSN values'
36
37
  };
37
38
 
38
- function getInvalidFields(record) {
39
- return record.get(/^(020|022)$/u).filter(field => { // eslint-disable-line prefer-named-capture-group
40
- // Check ISBN:
41
- if (field.tag === '020') {
42
- if (invalidField020(field)) {
43
- return true;
44
- }
39
+ function invalidISBN(isbn) {
40
+ // If value contains space, it's not necessarily crap. (It's typically something like "1234567890 (nid.)".)
41
+ // Check the first word in string:
42
+ if (isbn.indexOf(' ') > -1) {
43
+ // const arr = isbn.split(' ');
44
+ // console.info(`invalidISBN(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
45
+ // return invalidISBN(arr[0]);
46
+ return true;
47
+ }
45
48
 
46
- const subfield = field.subfields.find(sf => sf.code === 'a');
47
- const auditedIsbn = ISBN.audit(subfield.value);
48
- if (!auditedIsbn.validIsbn) {
49
- return true;
50
- }
51
- // Should we refactor code by adding a function that returns legal set of values,
52
- // and then we compare subfield.value against that list?
53
- const parsedIsbn = ISBN.parse(subfield.value);
54
- if (hyphenateISBN) {
55
- return !(subfield.value === parsedIsbn.isbn10h || subfield.value === parsedIsbn.isbn13h);
56
- }
49
+ const auditedIsbn = ISBN.audit(isbn);
50
+ if (!auditedIsbn.validIsbn) {
51
+ console.info(`Invalid ISBN detected: ${isbn}`); // eslint-disable-line no-console
52
+ return true;
53
+ }
54
+ return false;
55
+ }
57
56
 
58
- return !(subfield.value === parsedIsbn.isbn10 || subfield.value === parsedIsbn.isbn13);
57
+
58
+ function invalidField020(field) {
59
+ if (field.subfields && field.subfields.some(sf => invalidField020a(sf) || invalidField020z(sf))) {
60
+ return true;
61
+ }
62
+ return false;
63
+
64
+ function invalidField020a(subfield) {
65
+ if (subfield.code !== 'a') {
66
+ return false;
59
67
  }
60
- // Check ISSN:
61
- if (invalidField022(field)) {
68
+ if (invalidISBN(subfield.value)) {
62
69
  return true;
63
70
  }
71
+ return false;
72
+ }
64
73
 
65
- const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
74
+ function invalidField020z(subfield) {
75
+ if (subfield.code !== 'z' || !hyphenateISBN || invalidISBN(subfield.value)) {
76
+ return false;
77
+ }
78
+ // We are only interested in $z field if it is valid ISBN that requires hyphenation:
79
+ return subfield.value.indexOf('-') === -1;
80
+ }
81
+ }
66
82
 
67
- return !validateISSN(subfield.value);
68
- });
83
+ function subfieldRequiresHyphenation(subfield) {
84
+ if (subfield.code !== 'a' && subfield.code !== 'z') {
85
+ return false;
86
+ }
87
+ return requiresHyphenation(subfield.value);
69
88
 
70
- function invalidField020(field) {
71
- const subfieldA = field.subfields.find(sf => sf.code === 'a');
89
+ function requiresHyphenation(isbn) {
90
+ if (isbn.indexOf(' ') > -1) {
91
+ const arr = isbn.split(' ');
92
+ console.info(`requiresHyphenation(): Check '${arr[0]}' instead of '${isbn}'`); // eslint-disable-line no-console
93
+ return requiresHyphenation(arr[0]);
94
+ }
72
95
 
73
- if (subfieldA === undefined) {
74
- const subfieldZ = field.subfields.find(sf => sf.code === 'z');
75
- if (subfieldZ !== undefined) {
76
- return false;
96
+ if (invalidISBN(isbn)) {
97
+ return false;
98
+ }
99
+ console.info(`sfRH ${isbn}`); // eslint-disable-line no-console
100
+ const parsedIsbn = ISBN.parse(isbn);
101
+ if (hyphenateISBN) {
102
+ return !(isbn === parsedIsbn.isbn10h || isbn === parsedIsbn.isbn13h);
103
+ }
104
+ return false;
105
+ //return !(isbn === parsedIsbn.isbn10 || isbn === parsedIsbn.isbn13);
106
+ }
107
+ }
108
+
109
+ function getInvalidFields(record) {
110
+ //return record.get(/^(?:020|022)$/u).filter(field => {
111
+ return record.fields.filter(field => {
112
+ if (!field.subfields) {
113
+ return false;
114
+ }
115
+ // Check ISBN:
116
+ if (field.tag === '020') {
117
+ if (invalidField020(field)) {
118
+ return true;
77
119
  }
78
- return true;
120
+ return fieldRequiresHyphenation(field);
79
121
  }
80
122
 
81
- // If value contains space, it's not ok (it's typically something like "1234567890 (nid.)")
82
- if (subfieldA.value.indexOf(' ') > -1) {
83
- return true;
123
+ // Check ISSN:
124
+ if (field.tag === '022') {
125
+ if (invalidField022(field)) {
126
+ return true;
127
+ }
128
+
129
+ const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
130
+
131
+ return !validateISSN(subfield.value);
84
132
  }
85
133
  return false;
134
+ });
135
+
136
+ function fieldRequiresHyphenation(field) {
137
+ return field.subfields && field.subfields.some(sf => subfieldRequiresHyphenation(sf));
86
138
  }
87
139
 
88
140
  function invalidField022(field) {
@@ -138,49 +190,67 @@ export default ({hyphenateISBN = false, handleInvalid = false} = {}) => {
138
190
  }, {valid: false, messages: []});
139
191
  }
140
192
 
193
+
141
194
  function fix(record) {
142
195
  getInvalidFields(record).forEach(field => {
143
196
  if (field.tag === '020') {
144
- const subfield = field.subfields.find(sf => sf.code === 'a');
145
- if (subfield) {
146
- // ISBN is valid but is missing hyphens
147
- const normalizedValue = normalizeIsbnValue(subfield.value);
148
- if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement
149
- subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
150
- } else if (handleInvalid) { // eslint-disable-line functional/no-conditional-statement
151
- field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data
152
- record.removeSubfield(subfield, field);
153
- }
154
- }
155
- } else {
156
- const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
157
- if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
158
- field.subfields.push({code: 'y', value: trimSpaces(subfield.value)}); // eslint-disable-line functional/immutable-data
159
- record.removeSubfield(subfield, field);
160
- }
197
+ field.subfields.forEach(subfield => fixField020Subfield(field, subfield));
198
+ return;
199
+ }
200
+ // 022 ISSN:
201
+ const subfield = field.subfields.find(sf => sf.code === 'a' || sf.code === 'l');
202
+ if (subfield && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
203
+ // $a/$l => $y (bit overkill to add $z and remove $a/$l instead of just renaming)
204
+ field.subfields.push({code: 'y', value: subfield.value}); // eslint-disable-line functional/immutable-data
205
+ record.removeSubfield(subfield, field);
161
206
  }
162
207
  });
163
208
 
164
- function normalizeIsbnValue(value) {
165
- const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
166
- const auditResult = ISBN.audit(trimmedValue);
167
- if (auditResult.validIsbn) {
168
- const parsedIsbn = ISBN.parse(trimmedValue);
169
- if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement
170
- return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
209
+ /*
210
+ function trimISBN(value) {
211
+ return trimSpaces(value.replace(/\s$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
212
+ }
213
+ */
214
+
215
+ function fixField020Subfield(field, subfield) {
216
+ console.info(`fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
217
+ if (invalidISBN(subfield.value) || subfieldRequiresHyphenation(subfield)) {
218
+ console.info(` fixField020Subfield ${subfield.code} '${subfield.value}'`); // eslint-disable-line no-console
219
+ // ISBN is valid but is missing hyphens
220
+ const normalizedValue = normalizeIsbnValue(subfield.value);
221
+ if (normalizedValue !== undefined) { // eslint-disable-line functional/no-conditional-statement
222
+ subfield.value = normalizedValue; // eslint-disable-line functional/immutable-data
223
+ } else if (subfield.code === 'a' && handleInvalid) { // eslint-disable-line functional/no-conditional-statement
224
+ // $a => $z (bit overkill to add $z and remove $a instead of just renaming, but too lazy to fix/test thorougly)
225
+ field.subfields.push({code: 'z', value: subfield.value}); // eslint-disable-line functional/immutable-data
226
+ record.removeSubfield(subfield, field);
171
227
  }
172
- // Just trim
173
- return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
174
228
  }
175
- return undefined;
176
- }
229
+ return;
177
230
 
178
- function trimSpaces(value) {
179
- return value.replace(/\s/gu, '');
180
- }
231
+ function normalizeIsbnValue2(trimmedValue) {
232
+ //const trimmedValue = trimISBN(value); // NB! This might lose information that should be stored in $q...
233
+ const auditResult = ISBN.audit(trimmedValue);
234
+ if (auditResult.validIsbn) {
235
+ const parsedIsbn = ISBN.parse(trimmedValue);
236
+ if (hyphenateISBN) { // eslint-disable-line functional/no-conditional-statement
237
+ return trimmedValue.length === 10 ? parsedIsbn.isbn10h : parsedIsbn.isbn13h; // eslint-disable-line functional/immutable-data
238
+ }
239
+ // Just trim
240
+ return trimmedValue.length === 10 ? parsedIsbn.isbn10 : parsedIsbn.isbn13; // eslint-disable-line functional/immutable-data
241
+ }
242
+ return undefined;
243
+ }
181
244
 
182
- function trimISBN(value) {
183
- return trimSpaces(value.replace(/\s\D+$/gu, '')); // handle "1234567890 (nid.)" => "1234567890" as well as spaces
245
+ function normalizeIsbnValue(value) {
246
+ const trimmedValue = value.replace(/^\s+/gu, '');
247
+ if (trimmedValue.indexOf(' ') === -1) {
248
+ return normalizeIsbnValue2(trimmedValue);
249
+ }
250
+ const [head] = trimmedValue.split(' ');
251
+ // NB! We currently drop the tail part, as it prevents us from pairing doubles. Parametrize?
252
+ return normalizeIsbnValue2(head);
253
+ }
184
254
  }
185
255
  }
186
256
  };
@@ -60,6 +60,7 @@ describe('isbn-issn', () => {
60
60
  ind2: ' ',
61
61
  subfields: [{code: 'a', value: '90-6831-372-X'}]
62
62
  },
63
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-600-377-017-1'}]},
63
64
  {
64
65
  tag: '022',
65
66
  ind1: ' ',
@@ -101,7 +102,7 @@ describe('isbn-issn', () => {
101
102
  });
102
103
  });
103
104
 
104
- it('Finds the invalid 020 field', async () => {
105
+ it('020 field without $a and $z is ok in this context (= no invalid ISBNs)', async () => {
105
106
  const validator = await validatorFactory();
106
107
  const record = new MarcRecord({
107
108
  fields: [
@@ -116,7 +117,7 @@ describe('isbn-issn', () => {
116
117
  const result = await validator.validate(record);
117
118
 
118
119
  expect(result).to.eql({
119
- valid: false, messages: ['ISBN (undefined) is not valid']
120
+ valid: true
120
121
  });
121
122
  });
122
123
 
@@ -237,7 +238,10 @@ describe('isbn-issn', () => {
237
238
  {
238
239
  tag: '020', ind1: ' ', ind2: ' ',
239
240
  subfields: [{code: 'a', value: 'crappy val'}]
240
- }
241
+ },
242
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '97895234216609'}]},
243
+ // Just a sanity check due to earlier issues:
244
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}
241
245
  ]
242
246
  });
243
247
 
@@ -245,7 +249,9 @@ describe('isbn-issn', () => {
245
249
 
246
250
  expect(record.fields).to.eql([
247
251
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'foo'}]},
248
- {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]}
252
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: 'crappy val'}]},
253
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]},
254
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '97895234216609'}]}
249
255
  ]);
250
256
  });
251
257
 
@@ -323,7 +329,11 @@ describe('isbn-issn', () => {
323
329
  tag: '020',
324
330
  ind1: ' ',
325
331
  ind2: ' ',
326
- subfields: [{code: 'a', value: ' 9786003770171'}]
332
+ subfields: [
333
+ {code: 'a', value: '9786003770171 (nid.)'},
334
+ {code: 'z', value: '9786003770171 (nid.)'},
335
+ {code: 'z', value: 'foo bar'}
336
+ ]
327
337
  }
328
338
  ]
329
339
  });
@@ -331,12 +341,43 @@ describe('isbn-issn', () => {
331
341
 
332
342
  expect(record.fields).to.eql([
333
343
  {
334
- tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-600-377-017-1'}]
344
+ tag: '020',
345
+ ind1: ' ',
346
+ ind2: ' ',
347
+ subfields: [
348
+ {code: 'a', value: '978-600-377-017-1'},
349
+ {code: 'z', value: '978-600-377-017-1'},
350
+ {code: 'z', value: 'foo bar'}
351
+ ]
335
352
  }
336
353
  ]);
337
354
  });
338
355
 
339
- it('Adds hyphens to ISBN', async () => {
356
+ it('No relevant data', async () => {
357
+ const validator = await validatorFactory({hyphenateISBN: true});
358
+ const record = new MarcRecord({
359
+ fields: [
360
+ {
361
+ tag: '005',
362
+ value: 'whatever'
363
+ },
364
+ {
365
+ tag: '024',
366
+ ind1: ' ',
367
+ ind2: ' ',
368
+ subfields: [{code: 'a', value: ' 9786003770171'}]
369
+ }
370
+ ]
371
+ });
372
+ await validator.fix(record);
373
+
374
+ expect(record.fields).to.eql([
375
+ {tag: '005', value: 'whatever'},
376
+ {tag: '024', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: ' 9786003770171'}]}
377
+ ]);
378
+ });
379
+
380
+ it('Add hyphens to ISBN', async () => {
340
381
  const validator = await validatorFactory({hyphenateISBN: true});
341
382
  const record = new MarcRecord({
342
383
  fields: [
@@ -351,7 +392,12 @@ describe('isbn-issn', () => {
351
392
  {
352
393
  tag: '020', ind1: ' ', ind2: ' ',
353
394
  subfields: [{code: 'a', value: '386006004X (nid.)'}]
354
- }
395
+ },
396
+ {
397
+ tag: '020', ind1: ' ', ind2: ' ',
398
+ subfields: [{code: 'z', value: '9789916605325'}]
399
+ },
400
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '9789916605325 (sid.)'}]}
355
401
  ]
356
402
  });
357
403
 
@@ -360,7 +406,9 @@ describe('isbn-issn', () => {
360
406
  expect(record.fields).to.eql([
361
407
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '978-9916-605-32-5'}]},
362
408
  {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '91-7153-086-X'}]},
363
- {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]}
409
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'a', value: '3-86006-004-X'}]},
410
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]},
411
+ {tag: '020', ind1: ' ', ind2: ' ', subfields: [{code: 'z', value: '978-9916-605-32-5'}]}
364
412
  ]);
365
413
  });
366
414
  });