From 4424c5f2175855632b76eadc6f208a451fb41791 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 15 Sep 2023 10:58:07 +0200 Subject: [PATCH 1/3] resourcemanager/commonids: adding Common IDs for Bot Service & Bot Service Channel --- resourcemanager/commonids/bot_service.go | 127 ++++++++++ .../commonids/bot_service_channel.go | 235 ++++++++++++++++++ 2 files changed, 362 insertions(+) create mode 100644 resourcemanager/commonids/bot_service.go create mode 100644 resourcemanager/commonids/bot_service_channel.go diff --git a/resourcemanager/commonids/bot_service.go b/resourcemanager/commonids/bot_service.go new file mode 100644 index 0000000..0ac6fc3 --- /dev/null +++ b/resourcemanager/commonids/bot_service.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = BotServiceId{} + +// BotServiceId is a struct representing the Resource ID for a Bot Service +type BotServiceId struct { + SubscriptionId string + ResourceGroupName string + BotServiceName string +} + +// NewBotServiceID returns a new BotServiceId struct +func NewBotServiceID(subscriptionId string, resourceGroupName string, botServiceName string) BotServiceId { + return BotServiceId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + BotServiceName: botServiceName, + } +} + +// ParseBotServiceID parses 'input' into a BotServiceId +func ParseBotServiceID(input string) (*BotServiceId, error) { + parser := resourceids.NewParserFromResourceIdType(BotServiceId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := BotServiceId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.BotServiceName, ok = parsed.Parsed["botServiceName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "botServiceName", *parsed) + } + + return &id, nil +} + +// ParseBotServiceIDInsensitively parses 'input' case-insensitively into a BotServiceId +// note: this method should only be used for API response data and not user input +func ParseBotServiceIDInsensitively(input string) (*BotServiceId, error) { + parser := resourceids.NewParserFromResourceIdType(BotServiceId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := BotServiceId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.BotServiceName, ok = parsed.Parsed["botServiceName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "botServiceName", *parsed) + } + + return &id, nil +} + +// ValidateBotServiceID checks that 'input' can be parsed as a Bot Service ID +func ValidateBotServiceID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseBotServiceID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Bot Service ID +func (id BotServiceId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.BotService/botServices/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.BotServiceName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Bot Service ID +func (id BotServiceId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftBotService", "Microsoft.BotService", "Microsoft.BotService"), + resourceids.StaticSegment("staticBotServices", "botServices", "botServices"), + resourceids.UserSpecifiedSegment("botServiceName", "botServiceValue"), + } +} + +// String returns a human-readable description of this Bot Service ID +func (id BotServiceId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Bot Service Name: %q", id.BotServiceName), + } + return fmt.Sprintf("Bot Service (%s)", strings.Join(components, "\n")) +} diff --git a/resourcemanager/commonids/bot_service_channel.go b/resourcemanager/commonids/bot_service_channel.go new file mode 100644 index 0000000..f7741b1 --- /dev/null +++ b/resourcemanager/commonids/bot_service_channel.go @@ -0,0 +1,235 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = BotServiceChannelId{} + +// BotServiceChannelId is a struct representing the Resource ID for a Bot Service Channel +type BotServiceChannelId struct { + SubscriptionId string + ResourceGroupName string + BotServiceName string + ChannelType BotServiceChannelType +} + +// NewBotServiceChannelID returns a new BotServiceChannelId struct +func NewBotServiceChannelID(subscriptionId string, resourceGroupName string, botServiceName string, channelType BotServiceChannelType) BotServiceChannelId { + return BotServiceChannelId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + BotServiceName: botServiceName, + ChannelType: channelType, + } +} + +// ParseBotServiceChannelID parses 'input' into a BotServiceChannelId +func ParseBotServiceChannelID(input string) (*BotServiceChannelId, error) { + parser := resourceids.NewParserFromResourceIdType(BotServiceChannelId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := BotServiceChannelId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.BotServiceName, ok = parsed.Parsed["botServiceName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "botServiceName", *parsed) + } + + if v, ok := parsed.Parsed["channelType"]; true { + if !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "channelType", *parsed) + } + + channelType, err := parseBotServiceChannelType(v) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", v, err) + } + id.ChannelType = *channelType + } + + return &id, nil +} + +// ParseBotServiceChannelIDInsensitively parses 'input' case-insensitively into a BotServiceChannelId +// note: this method should only be used for API response data and not user input +func ParseBotServiceChannelIDInsensitively(input string) (*BotServiceChannelId, error) { + parser := resourceids.NewParserFromResourceIdType(BotServiceChannelId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := BotServiceChannelId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.BotServiceName, ok = parsed.Parsed["botServiceName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "botServiceName", *parsed) + } + + if v, ok := parsed.Parsed["channelType"]; true { + if !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "channelType", *parsed) + } + + channelType, err := parseBotServiceChannelType(v) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", v, err) + } + id.ChannelType = *channelType + } + + return &id, nil +} + +// ValidateBotServiceChannelID checks that 'input' can be parsed as a Bot Service Channel ID +func ValidateBotServiceChannelID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseBotServiceChannelID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Bot Service Channel ID +func (id BotServiceChannelId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.BotService/botServices/%s/channels/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.BotServiceName, id.ChannelType) +} + +// Segments returns a slice of Resource ID Segments which comprise this Bot Service Channel ID +func (id BotServiceChannelId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftBotService", "Microsoft.BotService", "Microsoft.BotService"), + resourceids.StaticSegment("staticBotServices", "botServices", "botServices"), + resourceids.UserSpecifiedSegment("botServiceName", "botServiceValue"), + resourceids.StaticSegment("staticChannels", "channels", "channels"), + resourceids.ConstantSegment("channelType", PossibleValuesForBotServiceChannelType(), string(AcsChatBotServiceChannelType)), + } +} + +// String returns a human-readable description of this Bot Service Channel ID +func (id BotServiceChannelId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Bot Service Name: %q", id.BotServiceName), + fmt.Sprintf("Channel Type: %q", id.ChannelType), + } + return fmt.Sprintf("Bot Service Channel (%s)", strings.Join(components, "\n")) +} + +type BotServiceChannelType = string + +const ( + AcsChatBotServiceChannelType BotServiceChannelType = "AcsChatChannel" + AlexaBotServiceChannelType BotServiceChannelType = "AlexaChannel" + DirectLineBotServiceChannelType BotServiceChannelType = "DirectLineChannel" + DirectLineSpeechBotServiceChannelType BotServiceChannelType = "DirectLineSpeechChannel" + EmailBotServiceChannelType BotServiceChannelType = "EmailChannel" + FacebookBotServiceChannelType BotServiceChannelType = "FacebookChannel" + KikChannelBotServiceChannelType BotServiceChannelType = "KikChannel" + LineBotServiceChannelType BotServiceChannelType = "LineChannel" + M365ExtensionsBotServiceChannelType BotServiceChannelType = "M365Extensions" + MsTeamsBotServiceChannelType BotServiceChannelType = "MsTeamsChannel" + OmniChannelBotServiceChannelType BotServiceChannelType = "OmniChannel" + OutlookBotServiceChannelType BotServiceChannelType = "OutlookChannel" + SearchAssistantBotServiceChannelType BotServiceChannelType = "SearchAssistant" + SkypeBotServiceChannelType BotServiceChannelType = "SkypeChannel" + SlackBotServiceChannelType BotServiceChannelType = "SlackChannel" + SmsBotServiceChannelType BotServiceChannelType = "SmsChannel" + TelegramBotServiceChannelType BotServiceChannelType = "TelegramChannel" + TelephonyBotServiceChannelType BotServiceChannelType = "TelephonyChannel" + WebChatBotServiceChannelType BotServiceChannelType = "WebChatChannel" +) + +func parseBotServiceChannelType(input string) (*BotServiceChannelType, error) { + vals := map[string]BotServiceChannelType{ + "AcsChatChannel": AcsChatBotServiceChannelType, + "AlexaChannel": AlexaBotServiceChannelType, + "DirectLineChannel": DirectLineBotServiceChannelType, + "DirectLineSpeechChannel": DirectLineSpeechBotServiceChannelType, + "EmailChannel": EmailBotServiceChannelType, + "KikChannel": FacebookBotServiceChannelType, + "FacebookChannel": KikChannelBotServiceChannelType, + "LineChannel": LineBotServiceChannelType, + "M365Extensions": M365ExtensionsBotServiceChannelType, + "MsTeamsChannel": MsTeamsBotServiceChannelType, + "Omnichannel": OmniChannelBotServiceChannelType, + "OutlookChannel": OutlookBotServiceChannelType, + "SearchAssistant": SearchAssistantBotServiceChannelType, + "SkypeChannel": SkypeBotServiceChannelType, + "SlackChannel": SlackBotServiceChannelType, + "SmsChannel": SmsBotServiceChannelType, + "TelegramChannel": TelegramBotServiceChannelType, + "TelephonyChannel": TelephonyBotServiceChannelType, + "WebChatChannel": WebChatBotServiceChannelType, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := BotServiceChannelType(input) + return &out, nil +} + +func PossibleValuesForBotServiceChannelType() []string { + return []string{ + string(AcsChatBotServiceChannelType), + string(AlexaBotServiceChannelType), + string(DirectLineBotServiceChannelType), + string(DirectLineSpeechBotServiceChannelType), + string(EmailBotServiceChannelType), + string(FacebookBotServiceChannelType), + string(KikChannelBotServiceChannelType), + string(LineBotServiceChannelType), + string(M365ExtensionsBotServiceChannelType), + string(MsTeamsBotServiceChannelType), + string(OmniChannelBotServiceChannelType), + string(OutlookBotServiceChannelType), + string(SearchAssistantBotServiceChannelType), + string(SkypeBotServiceChannelType), + string(SlackBotServiceChannelType), + string(SmsBotServiceChannelType), + string(TelegramBotServiceChannelType), + string(TelephonyBotServiceChannelType), + string(WebChatBotServiceChannelType), + } +} From 121edf20ab840462fbd4fb5055dd1ba82c840929 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 13 Dec 2023 13:04:10 +0100 Subject: [PATCH 2/3] resourcemanager/commonids: adding tests covering Bot Service ID --- resourcemanager/commonids/bot_service_test.go | 269 ++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 resourcemanager/commonids/bot_service_test.go diff --git a/resourcemanager/commonids/bot_service_test.go b/resourcemanager/commonids/bot_service_test.go new file mode 100644 index 0000000..4b383cf --- /dev/null +++ b/resourcemanager/commonids/bot_service_test.go @@ -0,0 +1,269 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import "testing" + +func TestNewBotServiceID(t *testing.T) { + id := NewBotServiceID("12345678-1234-9876-4563-123456789012", "example-resource-group", "botServiceValue") + + if id.SubscriptionId != "12345678-1234-9876-4563-123456789012" { + t.Fatalf("Expected %q but got %q for Segment 'SubscriptionId'", id.SubscriptionId, "12345678-1234-9876-4563-123456789012") + } + + if id.ResourceGroupName != "example-resource-group" { + t.Fatalf("Expected %q but got %q for Segment 'ResourceGroupName'", id.ResourceGroupName, "example-resource-group") + } + + if id.BotServiceName != "botServiceValue" { + t.Fatalf("Expected %q but got %q for Segment 'BotServiceName'", id.BotServiceName, "botServiceValue") + } +} + +func TestFormatBotServiceID(t *testing.T) { + actual := NewBotServiceID("12345678-1234-9876-4563-123456789012", "example-resource-group", "botServiceValue").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue" + if actual != expected { + t.Fatalf("Expected the Formatted ID to be %q but got %q", expected, actual) + } +} + +func TestParseBotServiceID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *BotServiceId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotServices", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue", + Expected: &BotServiceId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + BotServiceName: "botServiceValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseBotServiceID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.BotServiceName != v.Expected.BotServiceName { + t.Fatalf("Expected %q but got %q for BotServiceName", v.Expected.BotServiceName, actual.BotServiceName) + } + } +} + +func TestParseBotServiceIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *BotServiceId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotServices", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue", + Expected: &BotServiceId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + BotServiceName: "botServiceValue", + }, + }, + { + // Valid URI Insensitively + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/botServiceValue", + Expected: &BotServiceId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "eXaMpLe-ReSoUrCe-GrOuP", + BotServiceName: "botServiceValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/extra", + Error: true, + }, + { + // Invalid (Valid Uri with Extra segment) insensitively + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/botServiceValue/ExTra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseBotServiceIDInsensitively(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.BotServiceName != v.Expected.BotServiceName { + t.Fatalf("Expected %q but got %q for BotServiceName", v.Expected.BotServiceName, actual.BotServiceName) + } + } +} + +func TestSegmentsForBotServiceId(t *testing.T) { + segments := BotServiceId{}.Segments() + if len(segments) == 0 { + t.Fatalf("BotServiceId has no segments") + } + + uniqueNames := make(map[string]struct{}, 0) + for _, segment := range segments { + uniqueNames[segment.Name] = struct{}{} + } + if len(uniqueNames) != len(segments) { + t.Fatalf("Expected the Segments to be unique but got %q unique segments and %d total segments", len(uniqueNames), len(segments)) + } +} From d8ed462b02f0029e75fafab316fe84391b903ebf Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 13 Dec 2023 13:11:33 +0100 Subject: [PATCH 3/3] resourcemanager/commonids: adding tests covering the Bot Service Channel ID --- .../commonids/bot_service_channel_test.go | 310 ++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 resourcemanager/commonids/bot_service_channel_test.go diff --git a/resourcemanager/commonids/bot_service_channel_test.go b/resourcemanager/commonids/bot_service_channel_test.go new file mode 100644 index 0000000..3d1ea2b --- /dev/null +++ b/resourcemanager/commonids/bot_service_channel_test.go @@ -0,0 +1,310 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import "testing" + +func TestNewBotServiceChannelID(t *testing.T) { + id := NewBotServiceChannelID("12345678-1234-9876-4563-123456789012", "example-resource-group", "botServiceValue", EmailBotServiceChannelType) + + if id.SubscriptionId != "12345678-1234-9876-4563-123456789012" { + t.Fatalf("Expected %q but got %q for Segment 'SubscriptionId'", id.SubscriptionId, "12345678-1234-9876-4563-123456789012") + } + + if id.ResourceGroupName != "example-resource-group" { + t.Fatalf("Expected %q but got %q for Segment 'ResourceGroupName'", id.ResourceGroupName, "example-resource-group") + } + + if id.BotServiceName != "botServiceValue" { + t.Fatalf("Expected %q but got %q for Segment 'BotServiceName'", id.BotServiceName, "botServiceValue") + } + + if id.ChannelType != EmailBotServiceChannelType { + t.Fatalf("Expected %q but got %q for Segment 'ChannelType'", id.ChannelType, EmailBotServiceChannelType) + } +} + +func TestFormatBotServiceChannelID(t *testing.T) { + actual := NewBotServiceChannelID("12345678-1234-9876-4563-123456789012", "example-resource-group", "botServiceValue", EmailBotServiceChannelType).ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels/EmailChannel" + if actual != expected { + t.Fatalf("Expected the Formatted ID to be %q but got %q", expected, actual) + } +} + +func TestParseBotServiceChannelID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *BotServiceChannelId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotServices", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels/EmailChannel", + Expected: &BotServiceChannelId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + BotServiceName: "botServiceValue", + ChannelType: EmailBotServiceChannelType, + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels/EmailChannel/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseBotServiceChannelID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.BotServiceName != v.Expected.BotServiceName { + t.Fatalf("Expected %q but got %q for BotServiceName", v.Expected.BotServiceName, actual.BotServiceName) + } + } +} + +func TestParseBotServiceChannelIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *BotServiceChannelId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI (Insensitively) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotServices", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/bOtSeRvIcEvAlUe", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels", + Error: true, + }, + { + // Incomplete URI (Insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/bOtSeRvIcEvAlUe/ChAnNeLs", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels/EmailChannel", + Expected: &BotServiceChannelId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + BotServiceName: "botServiceValue", + ChannelType: EmailBotServiceChannelType, + }, + }, + { + // Valid URI Insensitively + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/botServiceValue/ChAnNeLs/EmAiLChAnNeL", + Expected: &BotServiceChannelId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "eXaMpLe-ReSoUrCe-GrOuP", + BotServiceName: "botServiceValue", + ChannelType: EmailBotServiceChannelType, + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.BotService/botServices/botServiceValue/channels/EmailChannel/extra", + Error: true, + }, + { + // Invalid (Valid Uri with Extra segment) insensitively + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-ReSoUrCe-GrOuP/pRoViDeRs/MiCrOsOfT.BoTsErViCe/BoTsErViCeS/botServiceValue/cHaNnElS/EmAiLChAnNeL/ExTra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseBotServiceChannelIDInsensitively(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.BotServiceName != v.Expected.BotServiceName { + t.Fatalf("Expected %q but got %q for BotServiceName", v.Expected.BotServiceName, actual.BotServiceName) + } + + if actual.ChannelType != v.Expected.ChannelType { + t.Fatalf("Expected %q but got %q for ChannelType", v.Expected.ChannelType, actual.ChannelType) + } + } +} + +func TestSegmentsForBotServiceChannelId(t *testing.T) { + segments := BotServiceChannelId{}.Segments() + if len(segments) == 0 { + t.Fatalf("BotServiceChannelId has no segments") + } + + uniqueNames := make(map[string]struct{}, 0) + for _, segment := range segments { + uniqueNames[segment.Name] = struct{}{} + } + if len(uniqueNames) != len(segments) { + t.Fatalf("Expected the Segments to be unique but got %q unique segments and %d total segments", len(uniqueNames), len(segments)) + } +}