Repository: amp-labs/connectors
Pull request #1668 (2025-05-19 21:55:07)

[CON-1618] feat(catalog): Read default ModuleInfo

Cobalt0s: > [!WARNING]
> <b>This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1668?utm_source=stack-comment-downstack-mergeability-warning" >on Graphite</a>.</b>
> <a href="https://graphite.dev/docs/merge-pull-requests">Learn more</a>

* **#1524** <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1524?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>: 9  dependent PRs ([#1525](https://github.com/amp-labs/connectors/pull/1525) <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1525?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>, [#1631](https://github.com/amp-labs/connectors/pull/1631) <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1631?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>, [#1632](https://github.com/amp-labs/connectors/pull/1632) <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1632?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> and 6 others)
* **#1627** <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1627?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>
* **#1635** <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1635?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>
* **#1668** <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1668?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> 👈 <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1668?utm_source=stack-comment-view-in-graphite" target="_blank">(View in Graphite)</a>
* **#1634** <a href="https://app.graphite.dev/github/pr/amp-labs/connectors/1634?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>
* `main`


<h2></h2>

This stack of pull requests is managed by <a href="https://graphite.dev?utm-source=stack-comment"><b>Graphite</b></a>. Learn more about <a href="https://stacking.dev/?utm_source=stack-comment">stacking</a>.
<!-- Current dependencies on/for this PR: -->

Patch:
diff --git a/providers/atlassian.go b/providers/atlassian.go
index f2a923cb..38710e28 100644
--- a/providers/atlassian.go
+++ b/providers/atlassian.go
@@ -26,6 +26,7 @@ func init() {
 			ExplicitWorkspaceRequired: true, // Needed for GetPostAuthInfo call
 		},
 		PostAuthInfoNeeded: true,
+		DefaultModule:      ModuleAtlassianJira,
 		Modules: &Modules{
 			ModuleAtlassianJira: {
 				BaseURL:     "https://api.atlassian.com/ex/jira/{{.cloudId}}/rest/api/3",
diff --git a/providers/aws.go b/providers/aws.go
index 94984d34..3d20dea5 100644
--- a/providers/aws.go
+++ b/providers/aws.go
@@ -23,6 +23,7 @@ func init() {
 			Subscribe: false,
 			Write:     false,
 		},
+		DefaultModule: ModuleAWSIdentityCenter,
 		Modules: &Modules{
 			ModuleAWSIdentityCenter: {
 				// TODO serviceDomain changes based on the request. This is not global to the connector.
diff --git a/providers/hubspot.go b/providers/hubspot.go
index 276804fc..fbeba94c 100644
--- a/providers/hubspot.go
+++ b/providers/hubspot.go
@@ -43,6 +43,7 @@ func init() { //nolint:funlen
 			Subscribe: false,
 			Write:     true,
 		},
+		DefaultModule: ModuleHubspotCRM,
 		Modules: &Modules{
 			ModuleHubspotCRM: {
 				BaseURL:     "https://api.hubapi.com/crm/v3",
diff --git a/providers/keap.go b/providers/keap.go
index 1c118941..1bc3fedf 100644
--- a/providers/keap.go
+++ b/providers/keap.go
@@ -38,6 +38,7 @@ func init() {
 			Subscribe: false,
 			Write:     false,
 		},
+		DefaultModule: ModuleKeapV1,
 		Modules: &Modules{
 			ModuleKeapV1: {
 				BaseURL:     "https://api.infusionsoft.com/v1",
diff --git a/providers/klaviyo.go b/providers/klaviyo.go
index 6d60dffa..a3614974 100644
--- a/providers/klaviyo.go
+++ b/providers/klaviyo.go
@@ -38,6 +38,7 @@ func init() {
 			Subscribe: false,
 			Write:     true,
 		},
+		DefaultModule: ModuleKlaviyo2024Oct15,
 		Modules: &Modules{
 			ModuleKlaviyo2024Oct15: {
 				BaseURL:     "https://a.klaviyo.com",
diff --git a/providers/marketo.go b/providers/marketo.go
index f3e2f538..c0bdab68 100644
--- a/providers/marketo.go
+++ b/providers/marketo.go
@@ -38,6 +38,7 @@ func init() {
 				ScopesField: "scope",
 			},
 		},
+		DefaultModule: ModuleMarketoLeads,
 		Modules: &Modules{
 			ModuleMarketoAssets: {
 				BaseURL:     "https://{{.workspace}}.mktorest.com/asset/v1",
diff --git a/providers/utils.go b/providers/utils.go
index 6286cdc7..e23ac4ea 100644
--- a/providers/utils.go
+++ b/providers/utils.go
@@ -168,46 +168,83 @@ func (i *ProviderInfo) GetOption(key string) (string, bool) {
 	return val, ok
 }
 
-// ReadModuleInfo is a version of ReadModuleInfoWithErr without an error.
-// Deprecated.
-// TODO this is a temporary impl which relies on default values for erroneous cases.
+// ReadModuleInfo finds information about the module.
+// If module is not found fallbacks to the default.
 func (i *ProviderInfo) ReadModuleInfo(moduleID common.ModuleID) *ModuleInfo {
-	result, _ := i.ReadModuleInfoWithErr(moduleID)
-
-	return result
-}
+	// Empty value fallback to the default value defined in ProviderInfo.
+	if moduleID == "" {
+		moduleID = i.defaultModuleOrRoot()
+	}
 
-func (i *ProviderInfo) ReadModuleInfoWithErr(moduleID common.ModuleID) (*ModuleInfo, error) {
+	// RootModule is inferred using the core values of ProviderInfo.
+	// On the surface those connectors are module agnostic.
 	rootModule := ModuleInfo{
 		BaseURL:     i.BaseURL,
 		DisplayName: i.DisplayName,
 		Support:     i.Support,
 	}
 
-	// Root or empty module name should default to provider information.
-	if moduleID == common.ModuleRoot || len(moduleID) == 0 {
-		return &rootModule, nil
+	// No modules exist. Fallback to the one and only RootModule.
+	if !i.hasModules() {
+		if moduleID != common.ModuleRoot {
+			// TODO the catalog should be checked almost at the "compile time".
+			// TODO There should be tests to ensure integrity. When anything is changed it should do consistency check.
+			slog.Warn("provider doesn't have modules while a module was requested",
+				"provider", i.DisplayName, "module", moduleID)
+		}
+
+		// Requesting root when no modules exist is allowed.
+		return &rootModule
 	}
 
-	if i.Modules == nil {
-		// Module ID was requested when no modules are defined on provider.
-		slog.Warn("modules info is not defined for provider while requested a module",
-			"provider", i.DisplayName, "modules", moduleID)
+	// Root module is providerInfo derived module.
+	if moduleID == common.ModuleRoot {
+		return &rootModule
+	}
 
-		return &rootModule, common.ErrMissingModule
+	// Find module.
+	module, ok := (*i.Modules)[moduleID] // nolint:varnamelen
+	if ok {
+		return &module
 	}
 
-	modules := *i.Modules
+	// Invalid module requested.
+	slog.Warn("module info is missing for a module",
+		"provider", i.DisplayName, "module", moduleID)
+
+	// Use fallback module to handle invalid module.
+	fallbackModule := i.defaultModuleOrRoot()
+
+	if fallbackModule == common.ModuleRoot {
+		return &rootModule
+	}
 
-	module, ok := modules[moduleID]
+	module, ok = (*i.Modules)[fallbackModule]
 	if !ok {
-		slog.Warn("module info is missing for a module",
-			"provider", i.DisplayName, "modules", moduleID)
+		slog.Warn("finding fallback module failed",
+			"provider", i.DisplayName, "module", fallbackModule)
+
+		return &rootModule
+	}
+
+	return &module
+}
+
+func (i *ProviderInfo) hasModules() bool {
+	return i.Modules != nil && len(*i.Modules) != 0
+}
+
+func (i *ProviderInfo) defaultModuleOrRoot() common.ModuleID {
+	if i.DefaultModule == "" {
+		if i.hasModules() {
+			slog.Warn("defaulting to root while provider supports multiple modulus",
+				"provider", i.DisplayName)
+		}
 
-		return &rootModule, common.ErrMissingModule
+		return common.ModuleRoot
 	}
 
-	return &module, nil
+	return i.DefaultModule
 }
 
 // UnauthorizedHandler is a function that is called when an unauthorized response is received.
diff --git a/providers/zendesk.go b/providers/zendesk.go
index 7dd858c3..386dd37f 100644
--- a/providers/zendesk.go
+++ b/providers/zendesk.go
@@ -29,6 +29,7 @@ func init() { // nolint:funlen
 			ExplicitScopesRequired:    true,
 			ExplicitWorkspaceRequired: true,
 		},
+		DefaultModule: ModuleZendeskTicketing,
 		Modules: &Modules{
 			ModuleZendeskTicketing: {
 				BaseURL:     "https://{{.workspace}}.zendesk.com/api/v2",
diff --git a/providers/zoom.go b/providers/zoom.go
index 687d7e6d..e2f29982 100644
--- a/providers/zoom.go
+++ b/providers/zoom.go
@@ -25,6 +25,7 @@ func init() {
 				ScopesField: "scope",
 			},
 		},
+		DefaultModule: ModuleZoomMeeting,
 		Modules: &Modules{
 			ModuleZoomUser: {
 				BaseURL:     "https://api.zoom.us/v2",


Test patch:
diff --git a/providers/utils_test.go b/providers/utils_test.go
index ef928cf5..bbcb315a 100644
--- a/providers/utils_test.go
+++ b/providers/utils_test.go
@@ -195,12 +195,12 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 	}
 
 	tests := []struct {
-		name        string
-		input       inType
-		expected    *ModuleInfo
-		expectedErr error
+		name     string
+		input    inType
+		expected *ModuleInfo
+		// TODO this method should check: `expectedErr error`
 	}{
-		// Root for providers that no modules.
+		// Root for providers that have no modules.
 		{
 			name: "Dynamics root module",
 			input: inType{
@@ -217,7 +217,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Capsule root module",
@@ -232,7 +231,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Proxy: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		// Root for providers that have multiple modules.
 		{
@@ -250,24 +248,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
-		},
-		{
-			name: "Atlassian root module",
-			input: inType{
-				provider: Atlassian,
-				moduleID: common.ModuleRoot,
-			},
-			expected: &ModuleInfo{
-				BaseURL:     "https://api.atlassian.com",
-				DisplayName: "Atlassian",
-				Support: Support{
-					Proxy: true,
-					Read:  true,
-					Write: true,
-				},
-			},
-			expectedErr: nil,
 		},
 		{
 			name: "Hubspot root module",
@@ -284,7 +264,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Keap root module",
@@ -299,7 +278,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Proxy: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Klaviyo root module",
@@ -316,7 +294,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Marketo root module",
@@ -334,7 +311,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zendesk root module",
@@ -352,7 +328,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zoom root module",
@@ -369,9 +344,8 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
-		// Unknown module for providers with no modulse.
+		// Unknown module for providers with no modules.
 		{
 			name: "Dynamics unknown module",
 			input: inType{
@@ -379,7 +353,7 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				vars:     createCatalogVars("workspace", "london"),
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
+			expected: &ModuleInfo{
 				BaseURL:     "https://london.api.crm.dynamics.com/api/data",
 				DisplayName: "Microsoft Dynamics CRM",
 				Support: Support{
@@ -388,7 +362,7 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Capsule unknown module",
@@ -396,7 +370,7 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				provider: Capsule,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
+			expected: &ModuleInfo{
 				BaseURL:     "https://api.capsulecrm.com/api",
 				DisplayName: "Capsule",
 				Support: Support{
@@ -405,25 +379,24 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: false,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
-		// Unknown module for providers with multiple modules.
+		// Unknown module for providers with multiple modules fallbacks to default.
 		{
 			name: "Atlassian unknown module",
 			input: inType{
 				provider: Atlassian,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://api.atlassian.com",
-				DisplayName: "Atlassian",
+			expected: &ModuleInfo{
+				BaseURL:     "https://api.atlassian.com/ex/jira/{{.cloudId}}/rest/api/3",
+				DisplayName: "Atlassian Jira",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Hubspot unknown module",
@@ -431,16 +404,15 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				provider: Hubspot,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://api.hubapi.com",
-				DisplayName: "HubSpot",
+			expected: &ModuleInfo{
+				BaseURL:     "https://api.hubapi.com/crm/v3",
+				DisplayName: "HubSpot CRM",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Keap unknown module",
@@ -448,16 +420,12 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				provider: Keap,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://api.infusionsoft.com",
-				DisplayName: "Keap",
-				Support: Support{
-					Proxy: true,
-					Read:  false,
-					Write: false,
-				},
+			expected: &ModuleInfo{
+				BaseURL:     "https://api.infusionsoft.com/v1",
+				DisplayName: "Keap Version 1",
+				Support:     Support{},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Klaviyo unknown module",
@@ -465,16 +433,15 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				provider: Klaviyo,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
+			expected: &ModuleInfo{
 				BaseURL:     "https://a.klaviyo.com",
-				DisplayName: "Klaviyo",
+				DisplayName: "Klaviyo (Version 2024-10-15)",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Marketo unknown module",
@@ -483,16 +450,15 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				vars:     createCatalogVars("workspace", "london"),
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://london.mktorest.com",
-				DisplayName: "Marketo",
+			expected: &ModuleInfo{
+				BaseURL:     "https://{{.workspace}}.mktorest.com/v1",
+				DisplayName: "Marketo (Leads)",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Zendesk unknown module",
@@ -501,16 +467,15 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				vars:     createCatalogVars("workspace", "london"),
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://london.zendesk.com",
-				DisplayName: "Zendesk Support",
+			expected: &ModuleInfo{
+				BaseURL:     "https://{{.workspace}}.zendesk.com/api/v2",
+				DisplayName: "Zendesk Ticketing",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		{
 			name: "Zoom unknown module",
@@ -518,16 +483,15 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				provider: Zoom,
 				moduleID: "random-module-name",
 			},
-			expected: &ModuleInfo{ // TODO temporary, favor an error
-				BaseURL:     "https://api.zoom.us",
-				DisplayName: "Zoom",
+			expected: &ModuleInfo{
+				BaseURL:     "https://api.zoom.us/v2",
+				DisplayName: "Zoom (Meeting)",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: common.ErrMissingModule,
+			// expectedErr: common.ErrMissingModule,
 		},
 		// Choosing non-root module for providers supporting several modules.
 		{
@@ -544,7 +508,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Atlassian Connect module",
@@ -560,7 +523,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Hubspot CRM module",
@@ -576,7 +538,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Keap V1 module",
@@ -589,7 +550,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				DisplayName: "Keap Version 1",
 				Support:     Support{},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Keap V2 module",
@@ -602,7 +562,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				DisplayName: "Keap Version 2",
 				Support:     Support{},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Klaviyo 2024-10-15 module",
@@ -618,7 +577,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Marketo Assets module",
@@ -634,7 +592,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Marketo Leads module",
@@ -650,7 +607,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zendesk Ticketing module",
@@ -666,7 +622,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zendesk Help Center module",
@@ -682,7 +637,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zoom User module",
@@ -698,7 +652,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Zoom Meeting module",
@@ -714,9 +667,8 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
-		// Empty module for providers that have no modules.
+		// Empty module for providers that have no modules defaults to root.
 		{
 			name: "Dynamics empty module",
 			input: inType{
@@ -733,7 +685,6 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
 			name: "Capsule empty module",
@@ -748,43 +699,38 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 					Proxy: true,
 				},
 			},
-			expectedErr: nil,
 		},
-		// Choosing empty module for providers supporting several modules.
+		// Choosing empty module for providers supporting several modules uses default from the Catalog.
 		{
-			name: "Klaviyo 2024-10-15 module",
+			name: "Klaviyo 2024-10-15 fallback to default module",
 			input: inType{
 				provider: Klaviyo,
 				moduleID: "",
 			},
 			expected: &ModuleInfo{
 				BaseURL:     "https://a.klaviyo.com",
-				DisplayName: "Klaviyo",
+				DisplayName: "Klaviyo (Version 2024-10-15)",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 		{
-			name: "Marketo Assets module",
+			name: "Marketo fallback to default module",
 			input: inType{
 				provider: Marketo,
 				vars:     createCatalogVars("workspace", "london"),
 				moduleID: "",
 			},
 			expected: &ModuleInfo{
-				BaseURL:     "https://london.mktorest.com",
-				DisplayName: "Marketo",
+				BaseURL:     "https://{{.workspace}}.mktorest.com/v1",
+				DisplayName: "Marketo (Leads)",
 				Support: Support{
-					Proxy: true,
 					Read:  true,
 					Write: true,
 				},
 			},
-			expectedErr: nil,
 		},
 	}
 
@@ -798,8 +744,8 @@ func TestReadModuleInfo(t *testing.T) { // nolint:funlen,maintidx
 				t.Fatalf("%s: bad test, failed to read info: (%v)", tt.name, err)
 			}
 
-			output, err := info.ReadModuleInfoWithErr(tt.input.moduleID)
-			testutils.CheckOutputWithError(t, tt.name, tt.expected, tt.expectedErr, output, err)
+			output := info.ReadModuleInfo(tt.input.moduleID)
+			testutils.CheckOutput(t, tt.name, tt.expected, output)
 		})
 	}
 }