@natlibfi/melinda-commons 14.0.0-alpha.5 → 14.0.1-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.
Files changed (37) hide show
  1. package/dist/subRecordPicker.js +27 -8
  2. package/dist/subRecordPicker.js.map +2 -2
  3. package/dist/subRecordPicker.test.js +13 -3
  4. package/dist/subRecordPicker.test.js.map +2 -2
  5. package/dist/utils.js +33 -0
  6. package/dist/utils.js.map +3 -3
  7. package/dist/utils.test.js +77 -1
  8. package/dist/utils.test.js.map +2 -2
  9. package/package.json +10 -10
  10. package/src/subRecordPicker.js +37 -8
  11. package/src/subRecordPicker.test.js +16 -3
  12. package/src/utils.js +74 -0
  13. package/src/utils.test.js +97 -2
  14. package/test-fixtures/subRecordPicker/readAllSubrecords/01/metadata.json +1 -0
  15. package/test-fixtures/subRecordPicker/readAllSubrecords/02/expected-records.json +632 -0
  16. package/test-fixtures/subRecordPicker/readAllSubrecords/02/metadata.json +22 -0
  17. package/test-fixtures/subRecordPicker/readAllSubrecords/02/response01.xml +136 -0
  18. package/test-fixtures/subRecordPicker/readAllSubrecords/02/response02.xml +71 -0
  19. package/test-fixtures/subRecordPicker/readAllSubrecords/03/expected-records.json +1 -0
  20. package/test-fixtures/subRecordPicker/readAllSubrecords/03/metadata.json +17 -0
  21. package/test-fixtures/subRecordPicker/readAllSubrecords/03/response01.xml +4 -0
  22. package/test-fixtures/subRecordPicker/readSomeSubrecords/01/metadata.json +1 -0
  23. package/test-fixtures/subRecordPicker/readSubrecordAmount/01/metadata.json +16 -0
  24. package/test-fixtures/subRecordPicker/readSubrecordAmount/01/response01.xml +4 -0
  25. package/test-fixtures/utils/isComponentRecord/record1.json +35 -0
  26. package/test-fixtures/utils/isComponentRecord/record2.json +35 -0
  27. package/test-fixtures/utils/isComponentRecord/record3.json +20 -0
  28. package/test-fixtures/utils/isComponentRecord/record4.json +20 -0
  29. package/test-fixtures/utils/isComponentRecord/record5.json +20 -0
  30. package/test-fixtures/utils/isComponentRecord/record6.json +35 -0
  31. package/test-fixtures/utils/isComponentRecord/record7.json +35 -0
  32. package/test-fixtures/utils/isTestRecord/record1.json +29 -0
  33. package/test-fixtures/utils/isTestRecord/record2.json +29 -0
  34. package/test-fixtures/utils/isTestRecord/record3.json +29 -0
  35. package/test-fixtures/utils/isTestRecord/record4.json +29 -0
  36. package/test-fixtures/utils/isTestRecord/record5.json +29 -0
  37. package/test-fixtures/utils/isTestRecord/record6.json +29 -0
package/src/utils.js CHANGED
@@ -28,6 +28,80 @@ export function isDeletedRecord(record) {
28
28
  }
29
29
  }
30
30
 
31
+ export function isTestRecord(record, checkNotesInf500 = true) {
32
+
33
+ return checkSta() || checkf500(checkNotesInf500);
34
+
35
+ function checkSta() {
36
+ return record.get(/^STA$/u).some(check);
37
+
38
+ function check({subfields}) {
39
+ const values = ['TEST'];
40
+ return subfields.some(({code, value}) => code === 'a' && values.includes(value));
41
+ }
42
+ }
43
+
44
+ function checkf500(checkNotesInf500) {
45
+ if (!checkNotesInf500) {
46
+ return false;
47
+ }
48
+
49
+ return record.get(/^500$/u).some(check);
50
+
51
+ // Recognize record as test record if it has f500 $a that has contents matching "test record" or "testitietue"
52
+ // Note: we might have false positives here, this test can be ignored by giving second param as 'false'
53
+ function check({subfields}) {
54
+ const testRecordRegexp = /testitietue|test record/iu;
55
+ return subfields.some(({code, value}) => code === 'a' && testRecordRegexp.test(value));
56
+ }
57
+ }
58
+
59
+ }
60
+
61
+
62
+ export function isComponentRecord(record, ignoreCollections = false, additionalHostFields = []) {
63
+
64
+ // Record is a component record if it has bibliografic level of a component in leader
65
+ // and/or has at least one host link field (f773)
66
+
67
+
68
+ // Ignore collections - optionally do not handle collections (LDR/07 'c')
69
+ // or collection subUnits (LDR/07 'd') as components, even if they do have f773
70
+
71
+ // https://www.loc.gov/marc/bibliographic/bdleader.html
72
+ // LDR/07
73
+ // c - Collection
74
+ // d - Subunit (in a collection)
75
+
76
+ if (ignoreCollections && ['c', 'd'].includes(record.leader[7])) {
77
+ return false;
78
+ }
79
+
80
+ // https://www.loc.gov/marc/bibliographic/bdleader.html
81
+ // LDR/07
82
+ // a - Monographic component part
83
+ // b - Serial component part
84
+ // d - Subunit (in a collection)
85
+
86
+ if (['a', 'b', 'd'].includes(record.leader[7])) {
87
+ return true;
88
+ }
89
+
90
+ // https://www.loc.gov/marc/bibliographic/bd773.html
91
+ // 773 - Host Item Entry (R)
92
+
93
+ // additionalHostFields (for example f973 for Viola's multihost componenets)
94
+ // optionally recognize fields given in additionalHostFields array as hostFields
95
+
96
+ const hostFields = additionalHostFields.concat('773');
97
+ const hostFieldPatternString = `^(${hostFields.join('|')})$`;
98
+ const hostFieldRegex = new RegExp(hostFieldPatternString, 'u');
99
+
100
+ const recordHasHostFields = record.get(hostFieldRegex).length > 0;
101
+ return recordHasHostFields;
102
+ //return record.get(/^773$/u).length > 0;
103
+ }
104
+
31
105
  export function parseBoolean(value) {
32
106
  if (value === undefined) {
33
107
  return false;
package/src/utils.test.js CHANGED
@@ -4,14 +4,15 @@ import {describe, it} from 'node:test';
4
4
  import assert from 'node:assert';
5
5
  import {MarcRecord} from '@natlibfi/marc-record';
6
6
  import {
7
- generateAuthorizationHeader, isDeletedRecord, parseBoolean, clone,
8
- getRecordTitle, getRecordStandardIdentifiers
7
+ generateAuthorizationHeader, isDeletedRecord, isTestRecord, parseBoolean, clone,
8
+ getRecordTitle, getRecordStandardIdentifiers, isComponentRecord
9
9
  } from './utils.js';
10
10
 
11
11
  MarcRecord.setValidationOptions({subfieldValues: false});
12
12
 
13
13
  const FIXTURES_PATH = path.join(import.meta.dirname, '../test-fixtures/utils');
14
14
 
15
+ // eslint-disable-next-line max-lines-per-function
15
16
  describe('utils', () => {
16
17
  describe('generateAuthorizationHeader', () => {
17
18
  it('Should create a proper Authorization header', () => {
@@ -70,6 +71,46 @@ describe('utils', () => {
70
71
  });
71
72
  });
72
73
 
74
+ describe('isTestRecord', () => {
75
+ it('Should find the record a test record (STA)', () => {
76
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record1.json'), 'utf8');
77
+ const record = new MarcRecord(JSON.parse(data));
78
+ assert.equal(isTestRecord(record), true);
79
+ });
80
+
81
+ it('Should find the record a test record (f500 "Testitietue.")', () => {
82
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record2.json'), 'utf8');
83
+ const record = new MarcRecord(JSON.parse(data));
84
+ assert.equal(isTestRecord(record), true);
85
+ });
86
+
87
+ it('Should find the record a test record (f500 "Foobar TESTITIETUE baz.")', () => {
88
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record3.json'), 'utf8');
89
+ const record = new MarcRecord(JSON.parse(data));
90
+ assert.equal(isTestRecord(record), true);
91
+ });
92
+
93
+ it('Should find the record a test record (f500 "test record")', () => {
94
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record4.json'), 'utf8');
95
+ const record = new MarcRecord(JSON.parse(data));
96
+ assert.equal(isTestRecord(record), true);
97
+ });
98
+
99
+ it('Should find the record not a test record', () => {
100
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record5.json'), 'utf8');
101
+ const record = new MarcRecord(JSON.parse(data));
102
+ assert.equal(isTestRecord(record), false);
103
+ });
104
+
105
+ it('Should find the record not a test record (f500 "test record", but configured not test f500)', () => {
106
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isTestRecord/record4.json'), 'utf8');
107
+ const record = new MarcRecord(JSON.parse(data));
108
+ assert.equal(isTestRecord(record, false), false);
109
+ });
110
+
111
+ });
112
+
113
+
73
114
  describe('parseBoolean', () => {
74
115
  it('Should parse undefined as false', () => {
75
116
  assert.equal(parseBoolean(undefined), false);
@@ -105,6 +146,60 @@ describe('utils', () => {
105
146
 
106
147
  });
107
148
 
149
+ describe('isComponentRecord', () => {
150
+ it('Should find out that the record is a component record (f773)', () => {
151
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record1.json'), 'utf8');
152
+ const record = new MarcRecord(JSON.parse(data));
153
+ assert.equal(isComponentRecord(record), true);
154
+ });
155
+
156
+ it('Should find out that the record is a component record (f773 + LDR/07 "a")', () => {
157
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record2.json'), 'utf8');
158
+ const record = new MarcRecord(JSON.parse(data));
159
+ assert.equal(isComponentRecord(record), true);
160
+ });
161
+
162
+ it('Should find out that the record is a component (LDR/07 "d")', () => {
163
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record3.json'), 'utf8');
164
+ const record = new MarcRecord(JSON.parse(data));
165
+ assert.equal(isComponentRecord(record), true);
166
+ });
167
+
168
+ it('Should find out that the record is not a component record', () => {
169
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record4.json'), 'utf8');
170
+ const record = new MarcRecord(JSON.parse(data));
171
+ assert.equal(isComponentRecord(record), false);
172
+ });
173
+
174
+ it('Should find out that the record is not a component record when ignoring collections', () => {
175
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record4.json'), 'utf8');
176
+ const record = new MarcRecord(JSON.parse(data));
177
+ assert.equal(isComponentRecord(record, true), false);
178
+ });
179
+
180
+
181
+ it('Should find out that the record is not a component record when ignoring collections (LDR/07 "d")', () => {
182
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record5.json'), 'utf8');
183
+ const record = new MarcRecord(JSON.parse(data));
184
+ assert.equal(isComponentRecord(record, true), false);
185
+ });
186
+
187
+
188
+ it('Should find out that the record is not a component record when ignoring collections (LDR/07 "c" and f773)', () => {
189
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record6.json'), 'utf8');
190
+ const record = new MarcRecord(JSON.parse(data));
191
+ assert.equal(isComponentRecord(record, true), false);
192
+ });
193
+
194
+ it('Should find out that the record is a component record when using additional host fields (f973)', () => {
195
+ const data = fs.readFileSync(path.join(FIXTURES_PATH, 'isComponentRecord/record7.json'), 'utf8');
196
+ const record = new MarcRecord(JSON.parse(data));
197
+ assert.equal(isComponentRecord(record, false, ['973']), true);
198
+ });
199
+
200
+ });
201
+
202
+
108
203
  describe('getRecordTitle', () => {
109
204
  [
110
205
  'Should find a title',
@@ -4,6 +4,7 @@
4
4
  "retrieveAll": true,
5
5
  "recordId": "000000123",
6
6
  "method": "readAllSubrecords",
7
+ "expectedAmount": 3,
7
8
  "requests": [
8
9
  {
9
10
  "method": "get",