@@ -3,7 +3,7 @@ import { describe, it } from 'mocha'
33import xpath from 'xpath'
44import { DOMParser as xmldom } from '@xmldom/xmldom'
55
6- import { removeBadNameUsageAttrs , unwrapSimpleElement , fixTitleAttributes , unwrapDateCreated , unwrapDateOther , fixDateCreatedKeyDate , fixDateCreatedQualifer , renameElement , removeElement , removeEmptyElements , removeAttribute , convertAuthorityElement , moveClassificationToSubject , wrapElement , wrapTextWithChild , moveAndRenameElement , convertNamePartDate , convertSubNameWrapper , wrapCopyInformation , wrapLocationTextContent , removeEmptyClassifications , convertSpeakerReleaseDetail , toStrictMODS } from './strict-mods.js'
6+ import { removeBadNameUsageAttrs , unwrapSimpleElement , fixTitleAttributes , unwrapDateCreated , unwrapDateOther , fixDateCreatedKeyDate , fixDateCreatedQualifer , renameElement , removeElement , removeEmptyElements , removeAttribute , convertAuthorityElement , moveClassificationToSubject , wrapElement , wrapTextWithChild , moveAndRenameElement , convertNamePartDate , convertSubNameWrapper , wrapCopyInformation , wrapLocationTextContent , removeEmptyClassifications , convertSpeakerReleaseDetail , convertArchivesWrapper , toStrictMODS } from './strict-mods.js'
77import { hasDirectTextContent } from './strict-mods-helpers.js'
88
99// Test fixtures
@@ -779,6 +779,100 @@ const fixtures = {
779779 expected : `<xml><mods>
780780 <titleInfo><title>Test</title></titleInfo>
781781 </mods></xml>`
782+ } ,
783+
784+ archivesWrapperBoth : {
785+ input : `<xml><mods>
786+ <titleInfo><title>Provost's Office Emails</title></titleInfo>
787+ <local>
788+ <archivesWrapper>
789+ <series>I. Administrative Materials</series>
790+ <subseries>7. General Admin Files</subseries>
791+ <seriesStaging>I. Administrative Materials\\7. General Admin Files</seriesStaging>
792+ </archivesWrapper>
793+ </local>
794+ </mods></xml>` ,
795+ expected : `<xml><mods>
796+ <titleInfo><title>Provost's Office Emails</title></titleInfo>
797+ <relatedItem type="series" displayLabel="subseries">
798+ <titleInfo>
799+ <title>7. General Admin Files</title>
800+ </titleInfo>
801+ <relatedItem type="series" displayLabel="series">
802+ <titleInfo>
803+ <title>I. Administrative Materials</title>
804+ </titleInfo>
805+ </relatedItem>
806+ </relatedItem>
807+ </mods></xml>`
808+ } ,
809+
810+ archivesWrapperSeriesOnly : {
811+ input : `<xml><mods>
812+ <titleInfo><title>College Newsletter</title></titleInfo>
813+ <local>
814+ <archivesWrapper>
815+ <series>II. Publications</series>
816+ <seriesStaging>II. Publications</seriesStaging>
817+ </archivesWrapper>
818+ </local>
819+ </mods></xml>` ,
820+ expected : `<xml><mods>
821+ <titleInfo><title>College Newsletter</title></titleInfo>
822+ <relatedItem type="series" displayLabel="series">
823+ <titleInfo>
824+ <title>II. Publications</title>
825+ </titleInfo>
826+ </relatedItem>
827+ </mods></xml>`
828+ } ,
829+
830+ archivesWrapperEmpty : {
831+ input : `<xml><mods>
832+ <titleInfo><title>Test Item</title></titleInfo>
833+ <local>
834+ <archivesWrapper>
835+ <series></series>
836+ <seriesStaging></seriesStaging>
837+ </archivesWrapper>
838+ </local>
839+ </mods></xml>` ,
840+ expected : `<xml><mods>
841+ <titleInfo><title>Test Item</title></titleInfo>
842+ </mods></xml>`
843+ } ,
844+
845+ archivesWrapperMultiple : {
846+ input : `<xml><mods>
847+ <titleInfo><title>Multiple Archives</title></titleInfo>
848+ <local>
849+ <archivesWrapper>
850+ <series>I. First Series</series>
851+ <subseries>A. First Subseries</subseries>
852+ </archivesWrapper>
853+ <archivesWrapper>
854+ <series>II. Second Series</series>
855+ </archivesWrapper>
856+ </local>
857+ </mods></xml>` ,
858+ expected : `<xml><mods>
859+ <titleInfo><title>Multiple Archives</title></titleInfo>
860+ <relatedItem type="series" displayLabel="subseries">
861+ <titleInfo>
862+ <title>A. First Subseries</title>
863+ </titleInfo>
864+ <relatedItem type="series" displayLabel="series">
865+ <titleInfo>
866+ <title>I. First Series</title>
867+ </titleInfo>
868+ </relatedItem>
869+ </relatedItem>
870+ <relatedItem type="series" displayLabel="series">
871+ <titleInfo>
872+ <title>II. Second Series</title>
873+ </titleInfo>
874+ </relatedItem>
875+ </mods></xml>`
782876 }
783877}
784878
@@ -3934,6 +4028,84 @@ describe('Strict MODS Conversion', () => {
39344028 } )
39354029 } )
39364030
4031+ describe ( 'convertArchivesWrapper' , ( ) => {
4032+ it ( 'should convert both series and subseries to nested relatedItem' , ( ) => {
4033+ const parser = new xmldom ( )
4034+ const doc = parser . parseFromString ( fixtures . archivesWrapperBoth . input , 'text/xml' )
4035+
4036+ convertArchivesWrapper ( doc )
4037+
4038+ const result = normalizeXML ( doc . toString ( ) )
4039+ const expected = normalizeXML ( fixtures . archivesWrapperBoth . expected )
4040+
4041+ assert . strictEqual ( result , expected )
4042+ } )
4043+
4044+ it ( 'should convert series only to single relatedItem' , ( ) => {
4045+ const parser = new xmldom ( )
4046+ const doc = parser . parseFromString ( fixtures . archivesWrapperSeriesOnly . input , 'text/xml' )
4047+
4048+ convertArchivesWrapper ( doc )
4049+
4050+ const result = normalizeXML ( doc . toString ( ) )
4051+ const expected = normalizeXML ( fixtures . archivesWrapperSeriesOnly . expected )
4052+
4053+ assert . strictEqual ( result , expected )
4054+ } )
4055+
4056+ it ( 'should remove empty archivesWrapper' , ( ) => {
4057+ const parser = new xmldom ( )
4058+ const doc = parser . parseFromString ( fixtures . archivesWrapperEmpty . input , 'text/xml' )
4059+
4060+ convertArchivesWrapper ( doc )
4061+
4062+ const result = normalizeXML ( doc . toString ( ) )
4063+ const expected = normalizeXML ( fixtures . archivesWrapperEmpty . expected )
4064+
4065+ assert . strictEqual ( result , expected )
4066+ } )
4067+
4068+ it ( 'should handle multiple archivesWrapper elements' , ( ) => {
4069+ const parser = new xmldom ( )
4070+ const doc = parser . parseFromString ( fixtures . archivesWrapperMultiple . input , 'text/xml' )
4071+
4072+ convertArchivesWrapper ( doc )
4073+
4074+ const result = normalizeXML ( doc . toString ( ) )
4075+ const expected = normalizeXML ( fixtures . archivesWrapperMultiple . expected )
4076+
4077+ assert . strictEqual ( result , expected )
4078+ } )
4079+
4080+ it ( 'should handle null document gracefully' , ( ) => {
4081+ const result = convertArchivesWrapper ( null )
4082+
4083+ assert . strictEqual ( result , null )
4084+ } )
4085+
4086+ it ( 'should verify nested structure is created correctly' , ( ) => {
4087+ const parser = new xmldom ( )
4088+ const doc = parser . parseFromString ( fixtures . archivesWrapperBoth . input , 'text/xml' )
4089+
4090+ convertArchivesWrapper ( doc )
4091+
4092+ const select = xpath . useNamespaces ( { } )
4093+ const outerRelated = select ( '//relatedItem[@displayLabel="subseries"]' , doc )
4094+ const innerRelated = select ( '//relatedItem[@displayLabel="series"]' , doc )
4095+
4096+ assert . strictEqual ( outerRelated . length , 1 , 'Should have one subseries relatedItem' )
4097+ assert . strictEqual ( innerRelated . length , 1 , 'Should have one series relatedItem' )
4098+ assert . strictEqual ( outerRelated [ 0 ] . getAttribute ( 'type' ) , 'series' )
4099+ assert . strictEqual ( innerRelated [ 0 ] . getAttribute ( 'type' ) , 'series' )
4100+
4101+ // Verify titles
4102+ const subseriesTitle = select ( 'titleInfo/title' , outerRelated [ 0 ] ) [ 0 ]
4103+ const seriesTitle = select ( 'titleInfo/title' , innerRelated [ 0 ] ) [ 0 ]
4104+ assert . strictEqual ( subseriesTitle . textContent , '7. General Admin Files' )
4105+ assert . strictEqual ( seriesTitle . textContent , 'I. Administrative Materials' )
4106+ } )
4107+ } )
4108+
39374109 describe ( 'Helper functions' , ( ) => {
39384110 describe ( 'hasDirectTextContent' , ( ) => {
39394111 it ( 'should return true for element with direct text content' , ( ) => {
0 commit comments