@@ -106,6 +106,19 @@ describe('GitHub Pull Requests view', function () {
106106 sinon . stub ( folderManager , 'createGitHubRepository' ) . resolves ( githubRepository ) ;
107107 }
108108
109+ function stackablePullRequest ( repository : MockGitHubRepository , number : number , base : string , head : string ) : PullRequestModel {
110+ const remote = repository . remote ;
111+ const rest = new PullRequestBuilder ( ) . number ( number )
112+ . base ( ref => ref . ref ( base ) ) . head ( ref => ref . ref ( head ) ) . build ( ) ;
113+ for ( const ref of [ rest . base , rest . head ] ) {
114+ ref . repo . owner . login = remote . owner ;
115+ ref . repo . name = remote . repositoryName ;
116+ ref . repo . clone_url = `https://github.com/${ remote . owner } /${ remote . repositoryName } .git` ;
117+ }
118+ return new PullRequestModel ( credentialStore , telemetry , repository , remote ,
119+ convertRESTPullRequestToRawPullRequest ( rest , repository ) ) ;
120+ }
121+
109122 afterEach ( function ( ) {
110123 provider . dispose ( ) ;
111124 discoveredRepository ?. dispose ( ) ;
@@ -136,7 +149,7 @@ describe('GitHub Pull Requests view', function () {
136149 assert . strictEqual ( options . canSelectMany , true ) ;
137150 } ) ;
138151
139- it ( 'does not enable multi-selection when stacks are disabled' , function ( ) {
152+ it ( 'disables multi-selection when created with stacks disabled' , function ( ) {
140153 setStacksEnabled ( false ) ;
141154 provider . dispose ( ) ;
142155 provider = new PullRequestsTreeDataProvider ( prsTreeModel , telemetry , context , reposManager ) ;
@@ -147,6 +160,64 @@ describe('GitHub Pull Requests view', function () {
147160 assert . strictEqual ( options . canSelectMany , false ) ;
148161 } ) ;
149162
163+ it ( 'applies multi-selection setting changes only when recreating the tree' , function ( ) {
164+ const configurationChanged = new vscode . EventEmitter < vscode . ConfigurationChangeEvent > ( ) ;
165+ context . subscriptions . push ( configurationChanged ) ;
166+ sinon . stub ( vscode . workspace , 'onDidChangeConfiguration' ) . callsFake ( configurationChanged . event ) ;
167+ provider . dispose ( ) ;
168+ provider = new PullRequestsTreeDataProvider ( prsTreeModel , telemetry , context , reposManager ) ;
169+ const event = {
170+ affectsConfiguration : ( section : string ) => section === 'githubPullRequests.experimental.stacks' ,
171+ } ;
172+
173+ for ( const enabled of [ false , true , false ] ) {
174+ const view = provider . view ;
175+ const treeCount = createTreeView . getCalls ( ) . filter ( call => call . args [ 0 ] === 'pr:github' ) . length ;
176+ setStacksEnabled ( enabled ) ;
177+ configurationChanged . fire ( event ) ;
178+ assert . strictEqual ( provider . view , view ) ;
179+ assert . strictEqual ( createTreeView . getCalls ( ) . filter ( call => call . args [ 0 ] === 'pr:github' ) . length , treeCount ) ;
180+
181+ provider . dispose ( ) ;
182+ provider = new PullRequestsTreeDataProvider ( prsTreeModel , telemetry , context , reposManager ) ;
183+ const tree = createTreeView . getCalls ( ) . filter ( call => call . args [ 0 ] === 'pr:github' ) . pop ( ) ;
184+ assert ( tree ) ;
185+ const options = tree . args [ 1 ] as { canSelectMany ?: boolean } ;
186+ assert . strictEqual ( options . canSelectMany , enabled ) ;
187+ }
188+ } ) ;
189+
190+ it ( 'updates stack actions when the setting changes on an existing multi-select tree' , function ( ) {
191+ const configurationChanged = new vscode . EventEmitter < vscode . ConfigurationChangeEvent > ( ) ;
192+ context . subscriptions . push ( configurationChanged ) ;
193+ sinon . stub ( vscode . workspace , 'onDidChangeConfiguration' ) . callsFake ( configurationChanged . event ) ;
194+ provider . dispose ( ) ;
195+ provider = new PullRequestsTreeDataProvider ( prsTreeModel , telemetry , context , reposManager ) ;
196+
197+ const url = 'https://github.com/aaa/bbb' ;
198+ const remote = new GitHubRemote ( 'origin' , url , new Protocol ( url ) , GitHubServerType . GitHubDotCom ) ;
199+ discoveredRepository = new MockGitHubRepository ( remote , credentialStore , telemetry , sinon ) ;
200+ const selected = [
201+ stackablePullRequest ( discoveredRepository , 1 , 'main' , 'D1' ) ,
202+ stackablePullRequest ( discoveredRepository , 2 , 'D1' , 'D2' ) ,
203+ ] . map ( model => Object . assign ( Object . create ( PRNode . prototype ) , { pullRequestModel : model } ) as PRNode ) ;
204+ sinon . stub ( provider . view , 'selection' ) . get ( ( ) => selected ) ;
205+ const executeCommand = sinon . spy ( vscode . commands , 'executeCommand' ) ;
206+ const treeCount = createTreeView . getCalls ( ) . filter ( call => call . args [ 0 ] === 'pr:github' ) . length ;
207+ const event = {
208+ affectsConfiguration : ( section : string ) => section === 'githubPullRequests.experimental.stacks' ,
209+ } ;
210+
211+ for ( const enabled of [ true , false , true ] ) {
212+ setStacksEnabled ( enabled ) ;
213+ executeCommand . resetHistory ( ) ;
214+ configurationChanged . fire ( event ) ;
215+ assert ( executeCommand . calledOnceWithExactly ( 'setContext' , 'github:canAddToStack' , enabled ) ) ;
216+ }
217+
218+ assert . strictEqual ( createTreeView . getCalls ( ) . filter ( call => call . args [ 0 ] === 'pr:github' ) . length , treeCount ) ;
219+ } ) ;
220+
150221 it ( 'does not offer or execute Add to Stack when stacks are disabled' , async function ( ) {
151222 setStacksEnabled ( false ) ;
152223 const showError = sinon . stub ( vscode . window , 'showErrorMessage' ) . resolves ( undefined ) ;
@@ -164,19 +235,8 @@ describe('GitHub Pull Requests view', function () {
164235 const remote = new GitHubRemote ( 'origin' , url , new Protocol ( url ) , GitHubServerType . GitHubDotCom ) ;
165236 const repository = new MockGitHubRepository ( remote , credentialStore , telemetry , sinon ) ;
166237 try {
167- const makePR = ( number : number , base : string , head : string ) => {
168- const rest = new PullRequestBuilder ( ) . number ( number )
169- . base ( ref => ref . ref ( base ) ) . head ( ref => ref . ref ( head ) ) . build ( ) ;
170- for ( const ref of [ rest . base , rest . head ] ) {
171- ref . repo . owner . login = remote . owner ;
172- ref . repo . name = remote . repositoryName ;
173- ref . repo . clone_url = `${ url } .git` ;
174- }
175- return new PullRequestModel ( credentialStore , telemetry , repository , remote ,
176- convertRESTPullRequestToRawPullRequest ( rest , repository ) ) ;
177- } ;
178- const bottom = makePR ( 1 , 'main' , 'D1' ) ;
179- const top = makePR ( 2 , 'D1' , 'D2' ) ;
238+ const bottom = stackablePullRequest ( repository , 1 , 'main' , 'D1' ) ;
239+ const top = stackablePullRequest ( repository , 2 , 'D1' , 'D2' ) ;
180240 const node = ( model : PullRequestModel ) => Object . assign ( Object . create ( PRNode . prototype ) , { pullRequestModel : model } ) as PRNode ;
181241 const selected = [ node ( bottom ) , node ( top ) ] ;
182242 const existing = {
0 commit comments