Skip to content
Merged
Show file tree
Hide file tree
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
43 changes: 43 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/powershell
{
"name": "PowerShell",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/powershell:lts-ubuntu-22.04",

"features": {
"ghcr.io/devcontainers/features/common-utils:2": {},
"ghcr.io/devcontainers/features/sshd:1": {},
"ghcr.io/devcontainers/features/dotnet:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},

"postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"",

// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.defaultProfile.linux": "pwsh"
},

// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.powershell",
"github.copilot",
"GitHub.copilot-chat",
"mhutchie.git-graph"
]
}
}

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

149 changes: 149 additions & 0 deletions Test/public/convertMeetingMembersToMarkdown.test.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
function Test_ConvertMeetingMembersToMarkdown_SingleCompany {

# Arrange
$input = "Alice Johnson <alice.johnson@alphatech.com>, `"Bob Smith (AlphaTech)`" <bob.smith@alphatech.com>"

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
$expected = @"
- Alphatech
- Alice Johnson <alice.johnson@alphatech.com>
- "Bob Smith (AlphaTech)" <bob.smith@alphatech.com>
"@
Assert-AreEqual -Expected $expected -Presented $result -Comment "Single company output should match expected format"
}

function Test_ConvertMeetingMembersToMarkdown_MultipleCompanies {

# Arrange
$input = "Alice Johnson <alice.johnson@alphatech.com>, `"Bob Smith (AlphaTech)`" <bob.smith@alphatech.com>, Alice Johnson <alice.johnson@betasoft.com>, `"Charlie Brown, David`" <charlie.brown@gammatech.com>, `"Emma Wilson, Frank`" <emma.wilson@gammatech.com>, `"Grace Lee, Henry`" <grace.lee@gammatech.com>"

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
$expected = @"
- Alphatech
- Alice Johnson <alice.johnson@alphatech.com>
- "Bob Smith (AlphaTech)" <bob.smith@alphatech.com>
- Betasoft
- Alice Johnson <alice.johnson@betasoft.com>
- Gammatech
- "Charlie Brown, David" <charlie.brown@gammatech.com>
- "Emma Wilson, Frank" <emma.wilson@gammatech.com>
- "Grace Lee, Henry" <grace.lee@gammatech.com>
"@
Assert-AreEqual -Expected $expected -Presented $result -Comment "Multiple companies should be sorted alphabetically"
}

function Test_ConvertMeetingMembersToMarkdown_DuplicateMemberDifferentCompanies {

# Arrange
$input = "Alice Johnson <alice.johnson@alphatech.com>, Alice Johnson <alice.johnson@betasoft.com>"

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
# Same person with different emails should appear in both company groups
$expected = @"
- Alphatech
- Alice Johnson <alice.johnson@alphatech.com>
- Betasoft
- Alice Johnson <alice.johnson@betasoft.com>
"@
Assert-AreEqual -Expected $expected -Presented $result -Comment "Same person with different emails should appear in both companies"
}

function Test_ConvertMeetingMembersToMarkdown_SpecialCharactersInName {

# Arrange
$input = "`"Bob Smith (AlphaTech)`" <bob.smith@alphatech.com>, `"Charlie Brown, David`" <charlie.brown@gammatech.com>"

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
# Names with special characters (parentheses, commas) should be preserved
$expected = @"
- Alphatech
- "Bob Smith (AlphaTech)" <bob.smith@alphatech.com>
- Gammatech
- "Charlie Brown, David" <charlie.brown@gammatech.com>
"@
Assert-AreEqual -Expected $expected -Presented $result -Comment "Names with special characters should be preserved"
}

function Test_ConvertMeetingMembersToMarkdown_EmptyInput {

# Arrange
$input = ""

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
Assert-AreEqual -Expected "" -Presented $result -Comment "Empty input should return empty string"
}

function Test_ConvertMeetingMembersToMarkdown_WhitespaceOnlyInput {

# Arrange
$input = " "

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
Assert-AreEqual -Expected "" -Presented $result -Comment "Whitespace-only input should return empty string"
}

function Test_ConvertMeetingMembersToMarkdown_SingleMember {

# Arrange
$input = "John Doe <john.doe@example.com>"

# Act
$result = Convert-MeetingMembersToMarkdown -MeetingMembers $input

# Assert
$expected = @"
- Example
- John Doe <john.doe@example.com>
"@
Assert-AreEqual -Expected $expected -Presented $result -Comment "Single member should work correctly"
}

function Test_ConvertMeetingsMembersToMarkdown_Big_sample{

$imput = @"
"Alice Anderson" <alice.anderson@deltalab.com>, "Amy Adams (She/Her)" <amy.adams@betasoft.com>, "Bob Brown" <bob.brown@betasoft.com>, "Charlie Chen" <charlie.chen@betasoft.com>, david.davis@betasoft.com, "David Dennis" <david.dennis@betasoft.com>, "Emma Evans, Eric" <emma.evans@deltalab.com>, emma.edwards@betasoft.com, "Frank Fields, Fiona" <frank.fields@deltalab.com>, george.garcia@bookings.betasoft.com, george.garcia@betasoft.com, "Grace (AlphaTech) Garcia" <grace.garcia@alphatech.com>, "Henry Harris" <henry.harris@alphatech.com>, "Iris Ingram" <iris.ingram@betasoft.com>, "Jack Johnson" <jack.johnson@betasoft.com>, "James Jackson" <james.jackson@betasoft.com>, "Jennifer Jones" <jennifer.jones@betasoft.com>, "Kevin Kim" <kevin.kim@alphatech.com>, "Kyle Knight" <kyle.knight@betasoft.com>, lisa.lee@betasoft.com, "Laura Lewis" <laura.lewis@alphatech.com>, "Mark Martinez" <mark.martinez@alphatech.com>
"@

$result = Convert-MeetingMembersToMarkdown -MeetingMembers $imput

Assert-AreEqual -Presented $result -Expected @"
- Alphatech
- "Grace (AlphaTech) Garcia" <grace.garcia@alphatech.com>
- "Henry Harris" <henry.harris@alphatech.com>
- "Kevin Kim" <kevin.kim@alphatech.com>
- "Laura Lewis" <laura.lewis@alphatech.com>
- "Mark Martinez" <mark.martinez@alphatech.com>
- Betasoft
- "Amy Adams (She/Her)" <amy.adams@betasoft.com>
- "Bob Brown" <bob.brown@betasoft.com>
- "Charlie Chen" <charlie.chen@betasoft.com>
- "David Dennis" <david.dennis@betasoft.com>
- "Iris Ingram" <iris.ingram@betasoft.com>
- "Jack Johnson" <jack.johnson@betasoft.com>
- "James Jackson" <james.jackson@betasoft.com>
- "Jennifer Jones" <jennifer.jones@betasoft.com>
- "Kyle Knight" <kyle.knight@betasoft.com>
- Deltalab
- "Alice Anderson" <alice.anderson@deltalab.com>
- "Emma Evans, Eric" <emma.evans@deltalab.com>
- "Frank Fields, Fiona" <frank.fields@deltalab.com>
"@
}
81 changes: 81 additions & 0 deletions private/parseMemberEmail.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@

function parseMemberEmail {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)][string]$MemberString
)

process {
$memberString = $MemberString.Trim()

if ([string]::IsNullOrWhiteSpace($memberString)) {
return $null
}

# Pattern: "Name" <email@domain.com> or Name <email@domain.com>
# The display name may contain quotes, commas, parentheses
$pattern = '^(.+?)\s*<([^>]+)>$'

if ($memberString -match $pattern) {
$displayName = $matches[1].Trim()
$email = $matches[2].Trim()

# Extract domain from email
$domain = ($email -split '@')[1]
if ($domain) {
# Get company name from domain (first part before any dots)
$company = ($domain -split '\.')[0]
# Capitalize first letter if company has content
if ($company.Length -gt 0) {
$company = $company.Substring(0, 1).ToUpper() + $company.Substring(1).ToLower()
}
else {
$company = "Unknown"
}
}
else {
$company = "Unknown"
}

return [PSCustomObject]@{
DisplayName = $displayName
Email = $email
Company = $company
OriginalFormat = $memberString
}
}

return $null
}
}

function groupMembersByCompany {
[CmdletBinding()]
param(
[Parameter(Mandatory)][object[]]$Members
)

# Filter out null members
$validMembers = $Members | Where-Object { $null -ne $_ }

if ($validMembers.Count -eq 0) {
return ""
}

# Group by company and sort by company name
$grouped = $validMembers | Group-Object -Property Company | Sort-Object -Property Name

$result = @()

foreach ($group in $grouped) {
# Add company header
$result += "- $($group.Name)"

# Add members with 4-space indentation
foreach ($member in $group.Group) {
$result += " - $($member.OriginalFormat)"
}
}

return ($result -join "`n")
}
58 changes: 58 additions & 0 deletions public/convertMeetingMembersToMarkdown.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

function Convert-MeetingMembersToMarkdown {
[CmdletBinding()]
param(
[Parameter(Position = 0, ValueFromPipeline)][string]$MeetingMembers
)

process {
if ([string]::IsNullOrWhiteSpace($MeetingMembers)) {
return ""
}

# Parse the comma-separated list, handling quoted names with commas
# Split on ', ' followed by a quote or a letter (not inside quotes)
$members = @()
$currentMember = ""
$inQuotes = $false

for ($i = 0; $i -lt $MeetingMembers.Length; $i++) {
$char = $MeetingMembers[$i]

if ($char -eq '"') {
$inQuotes = -not $inQuotes
$currentMember += $char
}
elseif ($char -eq ',' -and -not $inQuotes) {
# End of member
if (-not [string]::IsNullOrWhiteSpace($currentMember)) {
$members += $currentMember.Trim()
}
$currentMember = ""
}
else {
$currentMember += $char
}
}

# Add the last member
if (-not [string]::IsNullOrWhiteSpace($currentMember)) {
$members += $currentMember.Trim()
}

# Parse each member
$parsedMembers = $members | ForEach-Object { parseMemberEmail -MemberString $_ }

# Filter out nulls
$parsedMembers = $parsedMembers | Where-Object { $null -ne $_ }

if ($parsedMembers.Count -eq 0) {
return ""
}

# Group and format as markdown
$result = groupMembersByCompany -Members $parsedMembers

return $result
}
} Export-ModuleMember -Function 'Convert-MeetingMembersToMarkdown'
Loading