Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

Describe "Send-MailMessage" -Tags CI, RequireSudoOnUnix {
BeforeAll {
Register-PackageSource -Name nuget.org -Location https://api.nuget.org/v3/index.json -ProviderName NuGet -ErrorAction SilentlyContinue
if(-not ("netDumbster.smtp.SimpleSmtpServer" -as [type]))
{
Register-PackageSource -Name nuget.org -Location https://api.nuget.org/v3/index.json -ProviderName NuGet -ErrorAction SilentlyContinue

$nugetPackage = "netDumbster"
Install-Package -Name $nugetPackage -ProviderName NuGet -Scope CurrentUser -Force -Source 'nuget.org'

$nugetPackage = "netDumbster"
Install-Package -Name $nugetPackage -ProviderName NuGet -Scope CurrentUser -Force -Source 'nuget.org'
$dll = "$(Split-Path (Get-Package $nugetPackage).Source)\lib\netstandard2.0\netDumbster.dll"
Add-Type -Path $dll
}

$dll = "$(Split-Path (Get-Package $nugetPackage).Source)\lib\netstandard2.0\netDumbster.dll"
Add-Type -Path $dll
$DefaultInputObject = @{
From = "user01@example.com"
To = "user02@example.com"
Subject = "Subject $(Get-Date)"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
}

Describe "Send-MailMessage DRT Unit Tests" -Tags CI, RequireSudoOnUnix {
BeforeAll {
$server = [netDumbster.smtp.SimpleSmtpServer]::Start(25)

function Read-Mail
Expand All @@ -25,7 +36,7 @@ Describe "Send-MailMessage" -Tags CI, RequireSudoOnUnix {
}
}

AfterEach {
BeforeEach {
if($server)
{
$server.ClearReceivedEmail()
Expand All @@ -42,20 +53,46 @@ Describe "Send-MailMessage" -Tags CI, RequireSudoOnUnix {
$testCases = @(
@{
Name = "with mandatory parameters"
InputObject = $DefaultInputObject
}
@{
Name = "with ReplyTo"
InputObject = @{
From = "user01@example.com"
To = "user02@example.com"
ReplyTo = "noreply@example.com"
Subject = "Subject $(Get-Date)"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
}
}
@{
Name = "with ReplyTo"
Name = "with multiple To"
InputObject = @{
From = "user01@example.com"
To = "user02@example.com","user03@example.com","user04@example.com"
Subject = "Subject $(Get-Date)"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
}
}
@{
Name = "with multiple Cc"
InputObject = @{
From = "user01@example.com"
To = "user02@example.com"
ReplyTo = "noreply@example.com"
Cc = "user03@example.com","user04@example.com"
Subject = "Subject $(Get-Date)"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
}
}
@{
Name = "with multiple Bcc"
InputObject = @{
From = "user01@example.com"
To = "user02@example.com"
Bcc = "user03@example.com","user04@example.com"
Subject = "Subject $(Get-Date)"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
Expand All @@ -66,40 +103,54 @@ Describe "Send-MailMessage" -Tags CI, RequireSudoOnUnix {
InputObject = @{
From = "user01@example.com"
To = "user02@example.com"
ReplyTo = "noreply@example.com"
Body = "Body $(Get-Date)"
SmtpServer = "127.0.0.1"
}
}
)

It "Can send mail message using named parameters <Name>" -TestCases $testCases {
param($InputObject)

It "Shows obsolete message for cmdlet" {
$server | Should -Not -Be $null

$powershell = [PowerShell]::Create()

$null = $powershell.AddCommand("Send-MailMessage").AddParameters($InputObject).AddParameter("ErrorAction","SilentlyContinue")
$null = $powershell.AddCommand("Send-MailMessage").AddParameters($testCases[0].InputObject).AddParameter("ErrorAction","SilentlyContinue")

$powershell.Invoke()

$warnings = $powershell.Streams.Warning

$warnings.count | Should -BeGreaterThan 0
$warnings[0].ToString() | Should -BeLike "The command 'Send-MailMessage' is obsolete. *"
$warnings[0].ToString() | Should -BeLike "The command 'Send-MailMessage' is obsolete. *"
}

It "Can send mail message using named parameters <Name>" -TestCases $testCases {
param($InputObject)

$server | Should -Not -Be $null

Send-MailMessage @InputObject -ErrorAction SilentlyContinue

$mail = Read-Mail

$mail.FromAddress | Should -BeExactly $InputObject.From
$mail.ToAddresses | Should -BeExactly $InputObject.To
$mail.ToAddresses.Count | Should -BeExactly ($InputObject.To.Count + $InputObject.Cc.Count + $InputObject.Bcc.Count)
$mail.ToAddresses | Should -BeIn ([array]$InputObject.To + $InputObject.Cc + $InputObject.Bcc)

$mail.Headers["From"] | Should -BeExactly $InputObject.From
$mail.Headers["To"] | Should -BeExactly $InputObject.To
$mail.Headers["Reply-To"] | Should -BeExactly $InputObject.ReplyTo
If ($InputObject.Subject -ne $null) {
$mail.Headers["Subject"] | Should -BeExactly $InputObject.Subject
$mail.Headers["To"] | Should -Not -BeNullOrEmpty
$mail.Headers["To"].Split(", ") | Should -BeExactly $InputObject.To
If($InputObject.Cc)
{
$mail.Headers["Cc"] | Should -Not -BeNullOrEmpty
$mail.Headers["Cc"].Split(", ") | Should -BeExactly $InputObject.Cc
}
# BCC addresses can't be tested against mail message header, as this information is by design never included in the mail message itself.
If($InputObject.ReplyTo)
{
$mail.Headers["Reply-To"] | Should -BeExactly $InputObject.ReplyTo
}
$mail.Headers["Subject"] | Should -BeExactly $InputObject.Subject

$mail.MessageParts.Count | Should -BeExactly 1
$mail.MessageParts[0].BodyData | Should -BeExactly $InputObject.Body
Expand All @@ -117,16 +168,166 @@ Describe "Send-MailMessage" -Tags CI, RequireSudoOnUnix {
$mail = Read-Mail

$mail.FromAddress | Should -BeExactly $InputObject.From
$mail.ToAddresses | Should -BeExactly $InputObject.To
$mail.ToAddresses.Count | Should -BeExactly ($InputObject.To.Count + $InputObject.Cc.Count + $InputObject.Bcc.Count)
$mail.ToAddresses | Should -BeIn ([array]$InputObject.To + $InputObject.Cc + $InputObject.Bcc)

$mail.Headers["From"] | Should -BeExactly $InputObject.From
$mail.Headers["To"] | Should -BeExactly $InputObject.To
$mail.Headers["Reply-To"] | Should -BeExactly $InputObject.ReplyTo
If ($InputObject.Subject -ne $null) {
$mail.Headers["Subject"] | Should -BeExactly $InputObject.Subject
$mail.Headers["To"] | Should -Not -BeNullOrEmpty
$mail.Headers["To"].Split(", ") | Should -BeExactly $InputObject.To
If($InputObject.Cc)
{
$mail.Headers["Cc"] | Should -Not -BeNullOrEmpty
$mail.Headers["Cc"].Split(", ") | Should -BeExactly $InputObject.Cc
}
# BCC addresses can't be tested against mail message header, as this information is by design never included in the mail message itself.
If($InputObject.ReplyTo)
{
$mail.Headers["Reply-To"] | Should -BeExactly $InputObject.ReplyTo
}
$mail.Headers["Subject"] | Should -BeExactly $InputObject.Subject

$mail.MessageParts.Count | Should -BeExactly 1
$mail.MessageParts[0].BodyData | Should -BeExactly $InputObject.Body
}
}

Describe "Send-MailMessage Feature Tests" -Tags Feature, RequireSudoOnUnix {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TravisEz13 Make sense to use Feature tag?

@ThreeFive-O ThreeFive-O Apr 10, 2019

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iSazonov Feature tags for Pester are still available, but [feature] tag for commit messages in new PRs are now unnecessary, since all tests will be executed for PRs and daily builds on the CI agents.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Ilya means the -Tags Feature in the code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RDIL The way I understood it: Are -Tags Feature is still necessary for this kind of scenario. In my opinion it makes sense to use Feature tag, since the scope of the tests is much broader, than just some basic CI tests. Also those tests influence the time to run all test heavily.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They all seem appropriate to me

BeforeAll {
function Read-Mail
{
param()

if($server)
{
return $server.ReceivedEmail[0]
}
return $null
}
}

BeforeEach {
if($server)
{
$server.ClearReceivedEmail()
}
}

Context "Default Port 25" {
BeforeAll {
$server = [netDumbster.smtp.SimpleSmtpServer]::Start(25)
}

AfterAll {
if($server)
{
$server.Stop()
}
}

It "Can throw on wrong mail addresses" {
$server | Should -Not -Be $null

$obj = $DefaultInputObject.Clone()
$obj.To = "not_a_valid_mail.address"

{ Send-MailMessage @obj -ErrorAction Stop } | Should -Throw -ErrorId "FormatException,Microsoft.PowerShell.Commands.SendMailMessage"
}

It "Can send mail with free-form email address" {
$server | Should -Not -Be $null

$obj = $DefaultInputObject.Clone()
$obj.From = "User01 <user01@example.com>"
$obj.To = "User02 <user02@example.com>"

Send-MailMessage @obj -ErrorAction SilentlyContinue

$mail = Read-Mail

$mail.FromAddress | Should -BeExactly "user01@example.com"
$mail.ToAddresses | Should -BeExactly "user02@example.com"
}

It "Can send mail with high priority" {
$server | Should -Not -Be $null

Send-MailMessage @DefaultInputObject -Priority High -ErrorAction SilentlyContinue

$mail = Read-Mail
$mail.Priority | Should -BeExactly "urgent"
}

It "Can send mail with HTML content as body" {
$server | Should -Not -Be $null

$obj = $DefaultInputObject.Clone()
$obj.Body = "<html><body><h1>PowerShell</h1></body></html>"

Send-MailMessage @obj -BodyAsHtml -Encoding utf8 -ErrorAction SilentlyContinue

$mail = Read-Mail
$mail.Headers["content-type"] | Should -BeLike "text/html*"
$mail.MessageParts.Count | Should -BeExactly 1
$mail.MessageParts[0].BodyData | Should -Be $obj.Body
}

It "Can send mail with UTF8 encoding" {
$server | Should -Not -Be $null

$obj = $DefaultInputObject.Clone()
$obj.Body = "We ❤ PowerShell"

Send-MailMessage @obj -Encoding utf8Bom -ErrorAction SilentlyContinue

$mail = Read-Mail
$mail.MessageParts.Count | Should -BeExactly 1
$mail.Headers["content-transfer-encoding"] | Should -BeExactly "base64"
$utf8Text = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($mail.MessageParts[0].BodyData))
$utf8Text | Should -Be $obj.Body
}

It "Can send mail with attachments" {
$attachment1 = "TestDrive:\attachment1.txt"
$attachment2 = "TestDrive:\attachment2.txt"

$pngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAnElEQVR42u3RAQ0AAAgDoL9/aK3hHFSgyUw4o0KEIEQIQoQgRAhChAgRghAhCBGCECEIEYIQhAhBiBCECEGIEIQgRAhChCBECEKEIAQhQhAiBCFCECIEIQgRghAhCBGCECEIQYgQhAhBiBCECEEIQoQgRAhChCBECEIQIgQhQhAiBCFCEIIQIQgRghAhCBGCECFChCBECEKEIOS7BU5Hx50BmcQaAAAAAElFTkSuQmCC"

Set-Content $attachment1 -Value "First attachment"
Set-Content $attachment2 -AsByteStream -Value ([Convert]::FromBase64String($pngBase64))

$server | Should -Not -Be $null

Send-MailMessage @DefaultInputObject -Attachments $attachment1,$attachment2 -ErrorAction SilentlyContinue

$mail = Read-Mail
$mail.MessageParts.Count | Should -BeExactly 3

$txt = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($mail.MessageParts[1].BodyData)) -replace "`n|`r"
$txt | Should -BeExactly "First attachment"

($mail.MessageParts[2].BodyData -replace "`n|`r") | Should -BeExactly $pngBase64
}
}

Context "Custom Port 2525" {
BeforeAll {
$server = [netDumbster.smtp.SimpleSmtpServer]::Start(2525)
}

AfterAll {
if($server)
{
$server.Stop()
}
}

It "Can send mail message using custom port 2525" {
$server | Should -Not -Be $null
$server.ReceivedEmailCount | Should -BeExactly 0

Send-MailMessage @DefaultInputObject -Port 2525 -ErrorAction SilentlyContinue

$server.ReceivedEmailCount | Should -BeExactly 1
}
}
}