imapflow 1.2.5 → 1.2.6

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.
@@ -387,6 +387,12 @@ module.exports['Tools: formatDateTime with string'] = test => {
387
387
  test.done();
388
388
  };
389
389
 
390
+ module.exports['Tools: formatDateTime with invalid date string'] = test => {
391
+ let result = tools.formatDateTime('invalid-date-string');
392
+ test.equal(result, undefined);
393
+ test.done();
394
+ };
395
+
390
396
  // ============================================
391
397
  // formatFlag tests
392
398
  // ============================================
@@ -666,6 +672,52 @@ module.exports['Tools: parseEnvelope with invalid date'] = test => {
666
672
  test.done();
667
673
  };
668
674
 
675
+ module.exports['Tools: parseEnvelope with Buffer value'] = test => {
676
+ let entry = [
677
+ { value: Buffer.from('Mon, 15 Jun 2023 10:00:00 +0000') }, // date as Buffer
678
+ { value: Buffer.from('Buffer Subject') }, // subject as Buffer
679
+ [[{ value: Buffer.from('Sender Name') }, null, { value: Buffer.from('sender') }, { value: Buffer.from('example.com') }]], // from with Buffers
680
+ [], // sender
681
+ [], // reply-to
682
+ [], // to
683
+ [], // cc
684
+ [], // bcc
685
+ null, // in-reply-to
686
+ { value: Buffer.from('<msg-id@example.com>') } // message-id as Buffer
687
+ ];
688
+
689
+ let result = tools.parseEnvelope(entry);
690
+ test.equal(result.subject, 'Buffer Subject');
691
+ test.equal(result.from[0].address, 'sender@example.com');
692
+ test.equal(result.messageId, '<msg-id@example.com>');
693
+ test.done();
694
+ };
695
+
696
+ module.exports['Tools: parseEnvelope with empty address parts'] = test => {
697
+ // When both local part and domain are null/empty, address should be empty string
698
+ let entry = [
699
+ null, // date
700
+ null, // subject
701
+ [[{ value: 'Group Name' }, null, null, null]], // from with no email parts (group syntax)
702
+ [], // sender
703
+ [], // reply-to
704
+ [], // to
705
+ [], // cc
706
+ [], // bcc
707
+ null, // in-reply-to
708
+ null // message-id
709
+ ];
710
+
711
+ let result = tools.parseEnvelope(entry);
712
+ // Address '@' should be converted to empty string and filtered out if no name
713
+ test.ok(result.from);
714
+ // The entry has a name but no valid address, should still be included with empty address
715
+ test.equal(result.from.length, 1);
716
+ test.equal(result.from[0].name, 'Group Name');
717
+ test.equal(result.from[0].address, '');
718
+ test.done();
719
+ };
720
+
669
721
  // ============================================
670
722
  // getStructuredParams tests
671
723
  // ============================================
@@ -751,6 +803,158 @@ module.exports['Tools: parseBodystructure with attachment'] = test => {
751
803
  test.done();
752
804
  };
753
805
 
806
+ module.exports['Tools: parseBodystructure with md5'] = test => {
807
+ // Non-text type with extension data including md5
808
+ let entry = [
809
+ { value: 'APPLICATION' },
810
+ { value: 'OCTET-STREAM' },
811
+ null, // params
812
+ null, // id
813
+ null, // description
814
+ { value: 'BASE64' }, // encoding
815
+ { value: '1000' }, // size
816
+ { value: 'd41d8cd98f00b204e9800998ecf8427e' }, // md5
817
+ null, // disposition
818
+ null // language (to ensure we have enough elements)
819
+ ];
820
+
821
+ let result = tools.parseBodystructure(entry);
822
+ test.equal(result.type, 'application/octet-stream');
823
+ test.equal(result.md5, 'd41d8cd98f00b204e9800998ecf8427e');
824
+ test.done();
825
+ };
826
+
827
+ module.exports['Tools: parseBodystructure with language'] = test => {
828
+ // Non-text type with language extension
829
+ let entry = [
830
+ { value: 'APPLICATION' },
831
+ { value: 'PDF' },
832
+ null, // params
833
+ null, // id
834
+ null, // description
835
+ { value: 'BASE64' }, // encoding
836
+ { value: '5000' }, // size
837
+ null, // md5
838
+ null, // disposition
839
+ [{ value: 'EN' }, { value: 'DE' }], // language (array of values)
840
+ null // location (to ensure enough elements)
841
+ ];
842
+
843
+ let result = tools.parseBodystructure(entry);
844
+ test.equal(result.type, 'application/pdf');
845
+ test.ok(Array.isArray(result.language));
846
+ test.deepEqual(result.language, ['en', 'de']);
847
+ test.done();
848
+ };
849
+
850
+ module.exports['Tools: parseBodystructure with location'] = test => {
851
+ // Non-text type with location extension
852
+ let entry = [
853
+ { value: 'IMAGE' },
854
+ { value: 'PNG' },
855
+ null, // params
856
+ null, // id
857
+ null, // description
858
+ { value: 'BASE64' }, // encoding
859
+ { value: '10000' }, // size
860
+ null, // md5
861
+ null, // disposition
862
+ null, // language
863
+ { value: 'http://example.com/image.png' }, // location
864
+ null // extra element to ensure we have enough
865
+ ];
866
+
867
+ let result = tools.parseBodystructure(entry);
868
+ test.equal(result.type, 'image/png');
869
+ test.equal(result.location, 'http://example.com/image.png');
870
+ test.done();
871
+ };
872
+
873
+ module.exports['Tools: parseBodystructure with all extension fields'] = test => {
874
+ // Non-text type with all extension fields
875
+ let entry = [
876
+ { value: 'APPLICATION' },
877
+ { value: 'ZIP' },
878
+ [{ value: 'NAME' }, { value: 'archive.zip' }], // params
879
+ { value: '<id123@example.com>' }, // id
880
+ { value: 'A zip archive' }, // description
881
+ { value: 'BASE64' }, // encoding
882
+ { value: '50000' }, // size
883
+ { value: 'abc123def456' }, // md5
884
+ [{ value: 'ATTACHMENT' }, [{ value: 'FILENAME' }, { value: 'archive.zip' }]], // disposition with params
885
+ [{ value: 'EN' }], // language
886
+ { value: 'http://example.com/archive.zip' }, // location
887
+ null // extra element
888
+ ];
889
+
890
+ let result = tools.parseBodystructure(entry);
891
+ test.equal(result.type, 'application/zip');
892
+ test.equal(result.parameters.name, 'archive.zip');
893
+ test.equal(result.id, '<id123@example.com>');
894
+ test.equal(result.description, 'A zip archive');
895
+ test.equal(result.encoding, 'base64');
896
+ test.equal(result.size, 50000);
897
+ test.equal(result.md5, 'abc123def456');
898
+ test.equal(result.disposition, 'attachment');
899
+ test.equal(result.dispositionParameters.filename, 'archive.zip');
900
+ test.deepEqual(result.language, ['en']);
901
+ test.equal(result.location, 'http://example.com/archive.zip');
902
+ test.done();
903
+ };
904
+
905
+ module.exports['Tools: parseBodystructure with message/rfc822'] = test => {
906
+ // message/rfc822 has special handling with envelope and nested bodystructure
907
+ let nestedBody = [
908
+ { value: 'TEXT' },
909
+ { value: 'PLAIN' },
910
+ [{ value: 'CHARSET' }, { value: 'UTF-8' }],
911
+ null,
912
+ null,
913
+ { value: '7BIT' },
914
+ { value: '500' },
915
+ { value: '20' } // line count for text
916
+ ];
917
+
918
+ let envelope = [
919
+ { value: 'Mon, 15 Jun 2023 10:00:00 +0000' }, // date
920
+ { value: 'Nested Subject' }, // subject
921
+ [[null, null, { value: 'sender' }, { value: 'example.com' }]], // from
922
+ [],
923
+ [],
924
+ [],
925
+ [],
926
+ [], // sender, reply-to, to, cc, bcc
927
+ null, // in-reply-to
928
+ { value: '<nested@example.com>' } // message-id
929
+ ];
930
+
931
+ let entry = [
932
+ { value: 'MESSAGE' },
933
+ { value: 'RFC822' },
934
+ null, // params
935
+ null, // id
936
+ null, // description
937
+ { value: '7BIT' }, // encoding
938
+ { value: '10000' }, // size
939
+ envelope, // envelope
940
+ nestedBody, // nested bodystructure
941
+ { value: '100' }, // line count
942
+ null, // md5
943
+ null // disposition
944
+ ];
945
+
946
+ let result = tools.parseBodystructure(entry);
947
+ test.equal(result.type, 'message/rfc822');
948
+ test.equal(result.size, 10000);
949
+ test.equal(result.lineCount, 100);
950
+ test.ok(result.envelope);
951
+ test.equal(result.envelope.subject, 'Nested Subject');
952
+ test.ok(result.childNodes);
953
+ test.equal(result.childNodes.length, 1);
954
+ test.equal(result.childNodes[0].type, 'text/plain');
955
+ test.done();
956
+ };
957
+
754
958
  // ============================================
755
959
  // getDecoder tests
756
960
  // ============================================