From 887e3cd768ec89aa5cb679fcdb37e44c08dc9432 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Thu, 24 Oct 2024 13:36:03 +0200 Subject: [PATCH] Add EML parsing with new tests and examples Introduce new EML files with valid and invalid examples. Implement tests for EML parsing from readers and files, checking for both successful parsing and expected failures on invalid inputs. --- eml_test.go | 136 +++++++++++++++--- testdata/RFC5322-A1-1-invalid-from.eml | 8 ++ .../RFC5322-A1-1-invalid-from.eml.license | 3 + testdata/RFC5322-A1-1.eml | 8 ++ testdata/RFC5322-A1-1.eml.license | 3 + 5 files changed, 135 insertions(+), 23 deletions(-) create mode 100644 testdata/RFC5322-A1-1-invalid-from.eml create mode 100644 testdata/RFC5322-A1-1-invalid-from.eml.license create mode 100644 testdata/RFC5322-A1-1.eml create mode 100644 testdata/RFC5322-A1-1.eml.license diff --git a/eml_test.go b/eml_test.go index 44bfb54..1a2cbb2 100644 --- a/eml_test.go +++ b/eml_test.go @@ -6,11 +6,8 @@ package mail import ( "bytes" - "fmt" - "os" "strings" "testing" - "time" ) const ( @@ -22,6 +19,14 @@ Subject: Saying Hello Date: Fri, 21 Nov 1997 09:55:06 -0600 Message-ID: <1234@local.machine.example> +This is a message just to say hello. +So, "Hello".` + exampleMailRFC5322A11InvalidFrom = `From: §§§§§§§§§ +To: Mary Smith +Subject: Saying Hello +Date: Fri, 21 Nov 1997 09:55:06 -0600 +Message-ID: <1234@local.machine.example> + This is a message just to say hello. So, "Hello".` exampleMailPlainNoEnc = `Date: Wed, 01 Nov 2023 00:00:00 +0000 @@ -614,6 +619,108 @@ VGhpcyBpcyBhIHRlc3QgaW4gQmFzZTY0 --------------26A45336F6C6196BD8BBA2A2--` ) +func TestEMLToMsgFromReader(t *testing.T) { + t.Run("EMLToMsgFromReader via EMLToMsgFromString, check subject and encoding", func(t *testing.T) { + tests := []struct { + name string + emlString string + wantEncoding Encoding + wantSubject string + }{ + { + "RFC5322 A1.1 example mail", exampleMailRFC5322A11, EncodingUSASCII, + "Saying Hello"}, + { + "Plain text no encoding (7bit)", exampleMailPlain7Bit, EncodingUSASCII, + "Example mail // plain text without encoding", + }, + { + "Plain text no encoding", exampleMailPlainNoEnc, NoEncoding, + "Example mail // plain text without encoding", + }, + { + "Plain text quoted-printable", exampleMailPlainQP, EncodingQP, + "Example mail // plain text quoted-printable", + }, + { + "Plain text base64", exampleMailPlainB64, EncodingB64, + "Example mail // plain text base64", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + parsed, err := EMLToMsgFromString(tt.emlString) + if err != nil { + t.Fatalf("failed to parse EML string: %s", err) + } + if parsed.Encoding() != tt.wantEncoding.String() { + t.Errorf("failed to parse EML string: want encoding %s, got %s", tt.wantEncoding, + parsed.Encoding()) + } + gotSubject, ok := parsed.genHeader[HeaderSubject] + if !ok { + t.Fatalf("failed to parse EML string. No subject header found") + } + if len(gotSubject) != 1 { + t.Fatalf("failed to parse EML string, more than one subject header found") + } + if !strings.EqualFold(gotSubject[0], tt.wantSubject) { + t.Errorf("failed to parse EML string: want subject %s, got %s", tt.wantSubject, + gotSubject[0]) + } + }) + } + }) + t.Run("EMLToMsgFromReader fails on reader", func(t *testing.T) { + emlReader := bytes.NewBufferString("invalid") + if _, err := EMLToMsgFromReader(emlReader); err == nil { + t.Errorf("EML parsing with invalid EML string should fail") + } + }) + t.Run("EMLToMsgFromReader fails on parseEML", func(t *testing.T) { + emlReader := bytes.NewBufferString(exampleMailRFC5322A11InvalidFrom) + if _, err := EMLToMsgFromReader(emlReader); err == nil { + t.Errorf("EML parsing with invalid EML string should fail") + } + }) +} + +func TestEMLToMsgFromFile(t *testing.T) { + t.Run("EMLToMsgFromFile succeeds", func(t *testing.T) { + parsed, err := EMLToMsgFromFile("testdata/RFC5322-A1-1.eml") + if err != nil { + t.Fatalf("EMLToMsgFromFile failed: %s ", err) + } + if parsed.Encoding() != EncodingUSASCII.String() { + t.Errorf("EMLToMsgFromFile failed: want encoding %s, got %s", EncodingUSASCII, + parsed.Encoding()) + } + gotSubject, ok := parsed.genHeader[HeaderSubject] + if !ok { + t.Fatalf("failed to parse EML string. No subject header found") + } + if len(gotSubject) != 1 { + t.Fatalf("failed to parse EML string, more than one subject header found") + } + if !strings.EqualFold(gotSubject[0], "Saying Hello") { + t.Errorf("failed to parse EML string: want subject %s, got %s", "Saying Hello", + gotSubject[0]) + } + + }) + t.Run("EMLToMsgFromFile fails on file not found", func(t *testing.T) { + if _, err := EMLToMsgFromFile("testdata/not-existing.eml"); err == nil { + t.Errorf("EMLToMsgFromFile with invalid file should fail") + } + }) + t.Run("EMLToMsgFromFile fails on parseEML", func(t *testing.T) { + if _, err := EMLToMsgFromFile("testdata/RFC5322-A1-1-invalid-from.eml"); err == nil { + t.Errorf("EMLToMsgFromFile with invalid EML message should fail") + } + }) +} + +/* func TestEMLToMsgFromString(t *testing.T) { tests := []struct { name string @@ -621,26 +728,6 @@ func TestEMLToMsgFromString(t *testing.T) { enc string sub string }{ - { - "RFC5322 A1.1", exampleMailRFC5322A11, "7bit", - "Saying Hello", - }, - { - "Plain text no encoding (7bit)", exampleMailPlain7Bit, "7bit", - "Example mail // plain text without encoding", - }, - { - "Plain text no encoding", exampleMailPlainNoEnc, "8bit", - "Example mail // plain text without encoding", - }, - { - "Plain text quoted-printable", exampleMailPlainQP, "quoted-printable", - "Example mail // plain text quoted-printable", - }, - { - "Plain text base64", exampleMailPlainB64, "base64", - "Example mail // plain text base64", - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1009,3 +1096,6 @@ func stringToTempFile(data, name string) (string, string, error) { } return tempDir, filePath, nil } + + +*/ diff --git a/testdata/RFC5322-A1-1-invalid-from.eml b/testdata/RFC5322-A1-1-invalid-from.eml new file mode 100644 index 0000000..48a1248 --- /dev/null +++ b/testdata/RFC5322-A1-1-invalid-from.eml @@ -0,0 +1,8 @@ +From: §§§§§§§§ +To: Mary Smith +Subject: Saying Hello +Date: Fri, 21 Nov 1997 09:55:06 -0600 +Message-ID: <1234@local.machine.example> + +This is a message just to say hello. +So, "Hello". diff --git a/testdata/RFC5322-A1-1-invalid-from.eml.license b/testdata/RFC5322-A1-1-invalid-from.eml.license new file mode 100644 index 0000000..615ea2b --- /dev/null +++ b/testdata/RFC5322-A1-1-invalid-from.eml.license @@ -0,0 +1,3 @@ +// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors +// +// SPDX-License-Identifier: MIT diff --git a/testdata/RFC5322-A1-1.eml b/testdata/RFC5322-A1-1.eml new file mode 100644 index 0000000..adb1a85 --- /dev/null +++ b/testdata/RFC5322-A1-1.eml @@ -0,0 +1,8 @@ +From: John Doe +To: Mary Smith +Subject: Saying Hello +Date: Fri, 21 Nov 1997 09:55:06 -0600 +Message-ID: <1234@local.machine.example> + +This is a message just to say hello. +So, "Hello". \ No newline at end of file diff --git a/testdata/RFC5322-A1-1.eml.license b/testdata/RFC5322-A1-1.eml.license new file mode 100644 index 0000000..615ea2b --- /dev/null +++ b/testdata/RFC5322-A1-1.eml.license @@ -0,0 +1,3 @@ +// SPDX-FileCopyrightText: Copyright (c) 2022-2024 The go-mail Authors +// +// SPDX-License-Identifier: MIT