@@ -17,6 +17,10 @@ import {
1717 StartPrebuildResult ,
1818 SnapshotContext ,
1919 PrebuiltWorkspaceContext ,
20+ Branch ,
21+ CommitInfo ,
22+ Repository ,
23+ RepositoryInfo ,
2024} from "@gitpod/gitpod-protocol" ;
2125import * as chai from "chai" ;
2226import { Container } from "inversify" ;
@@ -36,6 +40,7 @@ import { HostContextProvider } from "../auth/host-context-provider";
3640import { AuthProvider } from "../auth/auth-provider" ;
3741import { Experiments } from "@gitpod/gitpod-protocol/lib/experiments/configcat-server" ;
3842import { SYSTEM_USER } from "../authorization/authorizer" ;
43+ import { RepositoryProvider } from "../repohost" ;
3944
4045const expect = chai . expect ;
4146
@@ -54,14 +59,98 @@ const gitpodEmptyContext = {
5459 private : false ,
5560 } ,
5661 normalizedContextURL : "https://github.com/gitpod-io/empty" ,
57- revision : "asdf " ,
62+ revision : "123456 " ,
5863 title : "gitpod-io/empty - main" ,
5964} ;
6065
66+ // MockRepositoryProvider is a class implementing the RepositoryProvider interface, which allows to pass in commitHistory and commitInfo as needed
67+ class MockRepositoryProvider implements RepositoryProvider {
68+ branches : Map < string , { branch : Branch ; commits : CommitInfo [ ] } > = new Map ( ) ;
69+
70+ addBranch ( branch : Omit < Branch , "commit" > , commits : CommitInfo [ ] ) {
71+ this . branches . set ( branch . name , {
72+ branch : {
73+ ...branch ,
74+ commit : {
75+ sha : head ( commits ) . sha ,
76+ author : head ( commits ) . author ,
77+ commitMessage : head ( commits ) . commitMessage ,
78+ } ,
79+ } ,
80+ commits,
81+ } ) ;
82+ }
83+
84+ async hasReadAccess ( user : any , owner : string , repo : string ) : Promise < boolean > {
85+ return true ;
86+ }
87+ async getBranch ( user : User , owner : string , repo : string , branchName : string ) : Promise < Branch > {
88+ const branch = this . branches . get ( branchName ) ;
89+ if ( ! branch ) {
90+ throw new Error ( "branch not found" ) ;
91+ }
92+ return branch . branch ;
93+ }
94+ async getRepo ( user : User , owner : string , repo : string ) : Promise < Repository > {
95+ return {
96+ host : "github.com" ,
97+ owner : "gitpod-io" ,
98+ name : "empty" ,
99+ cloneUrl : "https://github.com/gitpod-io/empty.git" ,
100+ defaultBranch : "main" ,
101+ } ;
102+ }
103+ async getCommitHistory ( user : User , owner : string , repo : string , ref : string , maxDepth : number ) : Promise < string [ ] > {
104+ const branch = this . branches . get ( ref ) ;
105+ if ( branch ) {
106+ return branch . commits . map ( ( c ) => c . sha ) ;
107+ }
108+
109+ for ( const b of this . branches . values ( ) ) {
110+ for ( const [ i , c ] of b . commits . entries ( ) ) {
111+ if ( c . sha === ref ) {
112+ // this commit, and everything before it
113+ return b . commits . slice ( 0 , i + 1 ) . map ( ( c ) => c . sha ) ;
114+ }
115+ }
116+ }
117+ throw new Error ( `ref ${ ref } not found` ) ;
118+ }
119+ async getCommitInfo ( user : User , owner : string , repo : string , ref : string ) : Promise < CommitInfo | undefined > {
120+ return headu ( this . branches . get ( ref ) ?. commits ) ;
121+ }
122+
123+ async getBranches ( user : User , owner : string , repo : string ) : Promise < Branch [ ] > {
124+ return Array . from ( this . branches . values ( ) ) . map ( ( b ) => b . branch ) ;
125+ }
126+
127+ async getUserRepos ( user : User ) : Promise < RepositoryInfo [ ] > {
128+ return [ ] ;
129+ }
130+ async searchRepos ( user : User , searchString : string , limit : number ) : Promise < RepositoryInfo [ ] > {
131+ return [ ] ;
132+ }
133+ }
134+
135+ function headu < T > ( arr : T [ ] | undefined ) : T | undefined {
136+ if ( ! arr || arr . length === 0 ) {
137+ return undefined ;
138+ }
139+ return arr [ arr . length - 1 ] ;
140+ }
141+
142+ function head < T > ( arr : T [ ] ) : T {
143+ if ( arr . length === 0 ) {
144+ throw new Error ( "empty array" ) ;
145+ }
146+ return arr [ arr . length - 1 ] ;
147+ }
148+
61149const SNAPSHOT_BUCKET = "https://gitpod.io/none-bucket" ;
62150
63151describe ( "ContextService" , async ( ) => {
64152 let container : Container ;
153+ let mockRepositoryProvider : MockRepositoryProvider ;
65154 let owner : User ;
66155 let member : User ;
67156 let stranger : User ;
@@ -91,41 +180,73 @@ describe("ContextService", async () => {
91180 normalizeContextURL : function ( contextURL : string ) : string {
92181 return contextURL + "normalizeContextURL" ;
93182 } ,
94- handle : function ( ctx : TraceContext , user : User , contextURL : string ) : Promise < WorkspaceContext > {
183+ handle : async function ( ctx : TraceContext , user : User , contextURL : string ) : Promise < WorkspaceContext > {
95184 const url = contextURL . replace ( "normalizeContextURL" , "" ) ;
96- switch ( url ) {
97- case "https://github.com/gitpod-io/empty" :
98- return gitpodEmptyContext as any ;
99- case `open-prebuild/${ prebuild . prebuildId } /https://github.com/gitpod-io/empty/tree/main` :
100- return {
101- ...gitpodEmptyContext ,
102- openPrebuildID : prebuild . prebuildId ,
103- } as any ;
104- case `snapshot/${ snapshot . id } ` : {
185+
186+ const cases = new Map < string , ( ) => WorkspaceContext > ( ) ;
187+ cases . set ( "https://github.com/gitpod-io/empty" , ( ) => {
188+ return gitpodEmptyContext as any ;
189+ } ) ;
190+
191+ if ( prebuild ) {
192+ cases . set (
193+ `open-prebuild/${ prebuild . prebuildId } /https://github.com/gitpod-io/empty/tree/main` ,
194+ ( ) => {
195+ return {
196+ ...gitpodEmptyContext ,
197+ openPrebuildID : prebuild . prebuildId ,
198+ } as any ;
199+ } ,
200+ ) ;
201+ }
202+ if ( snapshot ) {
203+ cases . set ( `snapshot/${ snapshot . id } ` , ( ) => {
105204 return {
106205 ...gitpodEmptyContext ,
107206 snapshotId : snapshot . id ,
108207 snapshotBucketId : SNAPSHOT_BUCKET ,
109208 } as any ;
110- }
111- case `snapshot/${ snapshot_stranger . id } ` : {
209+ } ) ;
210+ }
211+ if ( snapshot_stranger ) {
212+ cases . set ( `snapshot/${ snapshot_stranger . id } ` , ( ) => {
112213 return {
113214 ...gitpodEmptyContext ,
114215 snapshotId : snapshot_stranger . id ,
115216 snapshotBucketId : SNAPSHOT_BUCKET ,
116217 } as any ;
117- }
118- default :
119- return {
120- ref : "master" ,
121- } as any ;
218+ } ) ;
219+ }
220+ const c = cases . get ( url ) ;
221+ if ( c ) {
222+ return c ( ) ;
122223 }
224+
225+ const mainBranch = await mockRepositoryProvider . getBranch ( user , "gitpod-io" , "empty" , "main" ) ;
226+ const r : CommitContext = {
227+ title : mainBranch . commit . commitMessage ,
228+ ref : mainBranch . name ,
229+ refType : "branch" ,
230+ revision : mainBranch . commit . sha ,
231+ repository : await mockRepositoryProvider . getRepo ( user , "gitpod-io" , "empty" ) ,
232+ normalizedContextURL : mainBranch . htmlUrl ,
233+ } ;
234+ return r ;
123235 } ,
124236 } as any as ContextParser ) ;
125237 } ;
126238
127239 bindContextParser ( ) ;
128240
241+ mockRepositoryProvider = new MockRepositoryProvider ( ) ;
242+ mockRepositoryProvider . addBranch ( { name : "main" , htmlUrl : "https://github.com/gitpod-io/empty/tree/main" } , [
243+ {
244+ sha : gitpodEmptyContext . revision ,
245+ author : "some-dude" ,
246+ commitMessage : "some message" ,
247+ } ,
248+ ] ) ;
249+
129250 container . rebind ( HostContextProvider ) . toConstantValue ( {
130251 get : ( ) => {
131252 const authProviderId = "Public-GitHub" ;
@@ -138,30 +259,7 @@ describe("ContextService", async () => {
138259 } ,
139260 } ,
140261 services : {
141- repositoryProvider : {
142- hasReadAccess : async ( user : any , owner : string , repo : string ) => {
143- return true ;
144- } ,
145- getBranch : ( ) => {
146- return {
147- url : "https://github.com/gitpod-io/empty.git" ,
148- name : "main" ,
149- htmlUrl : "https://github.com/gitpod-io/empty" ,
150- commit : { } ,
151- } ;
152- } ,
153- getRepo : ( ) => {
154- return {
155- defaultBranch : "main" ,
156- } ;
157- } ,
158- getCommitHistory : ( ) => {
159- return [ ] ;
160- } ,
161- getCommitInfo : ( ) => {
162- return undefined ;
163- } ,
164- } ,
262+ repositoryProvider : mockRepositoryProvider ,
165263 } ,
166264 } ;
167265 } ,
0 commit comments