Skip to content

Commit 318f09c

Browse files
committed
Change logic for customization override to not override if user has manually selected a customization
1 parent c32c8f0 commit 318f09c

File tree

4 files changed

+126
-15
lines changed

4 files changed

+126
-15
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Change logic for customization override to not override if user has manually selected a customization"
4+
}

packages/core/src/codewhisperer/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export type {
2626
SendTelemetryEventResponse,
2727
TelemetryEvent,
2828
InlineChatEvent,
29+
Customization,
2930
} from './client/codewhispereruserclient.d.ts'
3031
export type { default as CodeWhispererUserClient } from './client/codewhispereruserclient.d.ts'
3132
export { SecurityPanelViewProvider } from './views/securityPanelViewProvider'
@@ -98,6 +99,6 @@ export * as diagnosticsProvider from './service/diagnosticsProvider'
9899
export * from './ui/codeWhispererNodes'
99100
export { SecurityScanError } from '../codewhisperer/models/errors'
100101
export * as CodeWhispererConstants from '../codewhisperer/models/constants'
101-
export { getSelectedCustomization } from './util/customizationUtil'
102+
export { getSelectedCustomization, setSelectedCustomization, baseCustomization } from './util/customizationUtil'
102103
export { Container } from './service/serviceContainer'
103104
export * from './util/gitUtil'

packages/core/src/codewhisperer/util/customizationUtil.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ export const baseCustomization = {
9191
),
9292
}
9393

94+
/**
95+
* Gets the customization that should be used for user requests. If a user has manually selected
96+
* a customization, always respect that choice. If not, check if the user is part of an AB
97+
* group assigned a specific customization. If so, use that customization. If not, use the
98+
* base customization.
99+
*/
94100
export const getSelectedCustomization = (): Customization => {
95101
if (
96102
!AuthUtil.instance.isCustomizationFeatureEnabled ||
@@ -105,21 +111,22 @@ export const getSelectedCustomization = (): Customization => {
105111
Object,
106112
{}
107113
)
108-
const result = selectedCustomizationArr[AuthUtil.instance.conn.label] || baseCustomization
109-
110-
// A/B case
111-
const customizationFeature = FeatureConfigProvider.getFeature(Features.customizationArnOverride)
112-
const arnOverride = customizationFeature?.value.stringValue
113-
const customizationOverrideName = customizationFeature?.variation
114-
if (arnOverride === undefined || arnOverride === '') {
115-
return result
114+
const selectedCustomization = selectedCustomizationArr[AuthUtil.instance.conn.label]
115+
116+
if (selectedCustomization && selectedCustomization.name !== baseCustomization.name) {
117+
return selectedCustomization
116118
} else {
117-
// A trick to prioritize arn from A/B over user's currently selected(for request and telemetry)
118-
// but still shows customization info of user's currently selected.
119-
return {
120-
arn: arnOverride,
121-
name: customizationOverrideName,
122-
description: result.description,
119+
const customizationFeature = FeatureConfigProvider.getFeature(Features.customizationArnOverride)
120+
const arnOverride = customizationFeature?.value.stringValue
121+
const customizationOverrideName = customizationFeature?.variation
122+
if (arnOverride === undefined) {
123+
return baseCustomization
124+
} else {
125+
return {
126+
arn: arnOverride,
127+
name: customizationOverrideName,
128+
description: baseCustomization.description,
129+
}
123130
}
124131
}
125132
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as sinon from 'sinon'
7+
import assert from 'assert'
8+
import { tryRegister } from '../testUtil'
9+
import {
10+
amazonQScopes,
11+
AuthUtil,
12+
baseCustomization,
13+
Customization,
14+
FeatureConfigProvider,
15+
getSelectedCustomization,
16+
refreshStatusBar,
17+
setSelectedCustomization,
18+
} from '../../codewhisperer'
19+
import { FeatureContext, globals } from '../../shared'
20+
import { resetCodeWhispererGlobalVariables } from '../codewhisperer/testUtil'
21+
import { createSsoProfile, createTestAuth } from '../credentials/testUtil'
22+
import { SsoConnection } from '../../auth'
23+
24+
const enterpriseSsoStartUrl = 'https://enterprise.awsapps.com/start'
25+
26+
describe('CodeWhisperer-customizationUtils', function () {
27+
let auth: ReturnType<typeof createTestAuth>
28+
let ssoConn: SsoConnection
29+
30+
before(async function () {
31+
createTestAuth(globals.globalState)
32+
tryRegister(refreshStatusBar)
33+
})
34+
35+
beforeEach(async function () {
36+
auth = createTestAuth(globals.globalState)
37+
ssoConn = await auth.createInvalidSsoConnection(
38+
createSsoProfile({ startUrl: enterpriseSsoStartUrl, scopes: amazonQScopes })
39+
)
40+
await resetCodeWhispererGlobalVariables()
41+
})
42+
43+
afterEach(function () {
44+
sinon.restore()
45+
})
46+
47+
it('Returns baseCustomization when not SSO', async function () {
48+
sinon.stub(AuthUtil.instance, 'isConnectionExpired').returns(false)
49+
sinon.stub(AuthUtil.instance, 'isConnected').returns(true)
50+
sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(false)
51+
sinon.stub(AuthUtil.instance, 'isCustomizationFeatureEnabled').value(true)
52+
const customization = getSelectedCustomization()
53+
54+
assert.strictEqual(customization.name, baseCustomization.name)
55+
})
56+
57+
it('Returns selectedCustomization when customization manually selected', async function () {
58+
sinon.stub(AuthUtil.instance, 'isConnectionExpired').returns(false)
59+
sinon.stub(AuthUtil.instance, 'isConnected').returns(true)
60+
sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(true)
61+
sinon.stub(AuthUtil.instance, 'isCustomizationFeatureEnabled').value(true)
62+
sinon.stub(AuthUtil.instance, 'conn').value(ssoConn)
63+
64+
const selectedCustomization: Customization = {
65+
arn: 'testCustomizationArn',
66+
name: 'testCustomizationName',
67+
description: 'testCustomizationDescription',
68+
}
69+
70+
await setSelectedCustomization(selectedCustomization)
71+
72+
const actualCustomization = getSelectedCustomization()
73+
74+
assert.strictEqual(actualCustomization.name, selectedCustomization.name)
75+
})
76+
77+
it('Returns AB customization', async function () {
78+
sinon.stub(AuthUtil.instance, 'isConnectionExpired').returns(false)
79+
sinon.stub(AuthUtil.instance, 'isConnected').returns(true)
80+
sinon.stub(AuthUtil.instance, 'isValidEnterpriseSsoInUse').returns(true)
81+
sinon.stub(AuthUtil.instance, 'isCustomizationFeatureEnabled').value(true)
82+
sinon.stub(AuthUtil.instance, 'conn').value(ssoConn)
83+
84+
const featureCustomization: FeatureContext = {
85+
name: 'testCustomizationName',
86+
value: {
87+
stringValue: 'testCustomizationArn',
88+
},
89+
variation: 'testCustomizationName',
90+
}
91+
sinon.stub(FeatureConfigProvider, 'getFeature').returns(featureCustomization)
92+
93+
await setSelectedCustomization(baseCustomization)
94+
95+
const returnedCustomization = getSelectedCustomization()
96+
97+
assert.strictEqual(returnedCustomization.name, featureCustomization.name)
98+
})
99+
})

0 commit comments

Comments
 (0)