33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6+ import * as vscode from "vscode" ;
67import * as sinon from "sinon" ;
78import sinonChai from "sinon-chai" ;
8- import * as vscode from "vscode" ;
99import { expect } from "chai" ;
1010import * as chai from "chai" ;
1111import * as Constants from "../../src/constants/constants" ;
1212import * as LocalizedConstants from "../../src/constants/locConstants" ;
1313import MainController from "../../src/controllers/mainController" ;
14- import ConnectionManager from "../../src/controllers/connectionManager" ;
14+ import ConnectionManager , { ConnectionInfo } from "../../src/controllers/connectionManager" ;
1515import SqlDocumentService , { ConnectionStrategy } from "../../src/controllers/sqlDocumentService" ;
16- import * as Telemetry from "../../src/telemetry/telemetry" ;
1716import SqlToolsServerClient from "../../src/languageservice/serviceclient" ;
18- import { IConnectionInfo } from "vscode-mssql" ;
17+ import { IConnectionInfo , IServerInfo } from "vscode-mssql" ;
18+ import { TreeNodeInfo } from "../../src/objectExplorer/nodes/treeNodeInfo" ;
19+ import { IConnectionProfile } from "../../src/models/interfaces" ;
20+ import { ConnectionStore } from "../../src/models/connectionStore" ;
21+ import { stubTelemetry } from "./utils" ;
1922
2023chai . use ( sinonChai ) ;
2124
@@ -101,6 +104,7 @@ suite("SqlDocumentService Tests", () => {
101104 } ) ;
102105
103106 test ( "handleNewQueryCommand should create a new query and update recents" , async ( ) => {
107+ stubTelemetry ( sandbox ) ;
104108 const editor : vscode . TextEditor = {
105109 document : { uri : "test_uri" } ,
106110 } as any ;
@@ -111,19 +115,17 @@ suite("SqlDocumentService Tests", () => {
111115 } ;
112116 connectionManager . getServerInfo . returns ( undefined as any ) ;
113117 connectionManager . handlePasswordBasedCredentials . resolves ( ) ;
114- const sendActionStub = sandbox . stub ( Telemetry , "sendActionEvent" ) ;
115118
116- const node : any = { connectionProfile : { } , nodeType : "Server" } ;
119+ const node : TreeNodeInfo = sandbox . createStubInstance ( TreeNodeInfo ) ;
120+ sandbox . stub ( node , "connectionProfile" ) . get ( ( ) => ( { } ) as IConnectionProfile ) ;
121+ sandbox . stub ( node , "nodeType" ) . get ( ( ) => "Server" ) ;
122+
117123 await sqlDocumentService . handleNewQueryCommand ( node , undefined ) ;
118124
119125 expect ( newQueryStub ) . to . have . been . calledOnce ;
120126 expect ( ( connectionManager as any ) . connectionStore . removeRecentlyUsed ) . to . have . been
121127 . calledOnce ;
122128 expect ( connectionManager . handlePasswordBasedCredentials ) . to . have . been . calledOnce ;
123- expect ( sendActionStub ) . to . have . been . calledOnce ;
124-
125- newQueryStub . restore ( ) ;
126- sendActionStub . restore ( ) ;
127129 } ) ;
128130
129131 test ( "handleNewQueryCommand should not create a new connection if new query fails" , async ( ) => {
@@ -168,9 +170,14 @@ suite("SqlDocumentService Tests", () => {
168170 } ) ;
169171
170172 test ( "handleNewQueryCommand uses OE selection when exactly one node is selected" , async ( ) => {
171- const nodeConnection = { server : "oeServer" } as any ;
173+ const nodeConnection = { server : "oeServer" } as IConnectionProfile ;
174+
175+ const selectedNode : TreeNodeInfo = sandbox . createStubInstance ( TreeNodeInfo ) ;
176+ sandbox . stub ( selectedNode , "connectionProfile" ) . get ( ( ) => nodeConnection ) ;
177+ sandbox . stub ( selectedNode , "nodeType" ) . get ( ( ) => "Server" ) ;
178+
172179 mainController . objectExplorerTree = {
173- selection : [ { connectionProfile : nodeConnection , nodeType : "Database" } ] ,
180+ selection : [ selectedNode ] ,
174181 } as any ;
175182 connectionManager . handlePasswordBasedCredentials . resolves ( ) ;
176183 connectionManager . connectionStore = {
@@ -192,6 +199,59 @@ suite("SqlDocumentService Tests", () => {
192199 newQueryStub . restore ( ) ;
193200 } ) ;
194201
202+ test ( "handleNewQueryCommand refreshes Entra token info on source node" , async ( ) => {
203+ stubTelemetry ( sandbox ) ;
204+
205+ const oldToken = {
206+ azureAccountToken : "oldToken" ,
207+ expiresOn : Date . now ( ) / 1000 - 60 , // 60 seconds in the past; not that the test actually requires this to be expired
208+ } ;
209+
210+ const newToken = {
211+ azureAccountToken : "refreshedToken" ,
212+ expiresOn : oldToken . expiresOn + 600 + 60 , // 10 minutes in the future (plus making up for the past offset)
213+ } ;
214+
215+ const nodeConnection = {
216+ server : "server" ,
217+ ...oldToken ,
218+ } as IConnectionProfile ;
219+
220+ const node = {
221+ connectionProfile : nodeConnection ,
222+ nodeType : "Server" ,
223+ updateEntraTokenInfo : sandbox . stub ( ) ,
224+ } as unknown as TreeNodeInfo ;
225+
226+ connectionManager . handlePasswordBasedCredentials . resolves ( ) ;
227+
228+ const connectionStoreStub = sandbox . createStubInstance ( ConnectionStore ) ;
229+
230+ connectionManager . connectionStore = connectionStoreStub ;
231+ connectionManager . getServerInfo . returns ( { } as IServerInfo ) ;
232+ connectionManager . getConnectionInfo . returns ( { } as ConnectionInfo ) ;
233+
234+ const editor : vscode . TextEditor = {
235+ document : { uri : vscode . Uri . parse ( "untitled:tokenTest" ) } ,
236+ } as vscode . TextEditor ;
237+
238+ sandbox . stub ( sqlDocumentService , "newQuery" ) . callsFake ( async ( opts ) => {
239+ expect ( opts . connectionInfo ) . to . equal ( nodeConnection ) ;
240+ Object . assign ( opts . connectionInfo , newToken ) ;
241+
242+ return editor ;
243+ } ) ;
244+
245+ expect ( nodeConnection . azureAccountToken ) . to . equal ( oldToken . azureAccountToken ) ;
246+ expect ( nodeConnection . expiresOn ) . to . equal ( oldToken . expiresOn ) ;
247+
248+ await sqlDocumentService . handleNewQueryCommand ( node , undefined ) ;
249+
250+ expect ( node . updateEntraTokenInfo ) . to . have . been . calledOnceWith ( nodeConnection ) ;
251+ expect ( nodeConnection . azureAccountToken ) . to . equal ( newToken . azureAccountToken ) ;
252+ expect ( nodeConnection . expiresOn ) . to . equal ( newToken . expiresOn ) ;
253+ } ) ;
254+
195255 test ( "handleNewQueryCommand prompts for connection when no context" , async ( ) => {
196256 // clear last active and OE selection
197257 sqlDocumentService [ "_lastActiveConnectionInfo" ] = undefined ;
0 commit comments