import { Context , Probot , createProbot , ProbotOctokit } from 'probot' ; import { describe , it , beforeEach , afterEach } from 'mocha' ; import nock from 'nock' ; import * as assert from 'assert' ; import { resolve } from 'path' ; import fs from 'fs' ; import * as sinon from 'sinon' ; import snapshot from 'snap-shot-it' ; import { handler } from '../src/auto-label' ; import * as botConfigModule from '@google-automations/bot-config-utils' ; import { ConfigChecker } from '@google-automations/bot-config-utils' ; import * as helper from '../src/helper' ; nock . disableNetConnect ( ) ; const sandbox = sinon . createSandbox ( ) ; const fixturesPath = resolve ( __dirname , '../../test/fixtures' ) ; function createConfigResponse ( configFile ) { const config = fs . readFileSync ( resolve ( fixturesPath , 'config' , configFile ) ) ; const base64Config = config . toString ( 'base64' ) ; return { size : base64Config . length , content : base64Config , encoding : 'base64' , } ; } function fetchConfig ( configFile ) { return nock ( 'https://api.github.com' ) . get ( `/repos/testOwner/testRepo/contents/.github%2F${ helper . CONFIG_FILE_NAME }` ) . reply ( 200 , createConfigResponse ( configFile ) ) ; } function fetchFilesInPR ( configFile ) { return nock ( 'https://api.github.com' ) . get ( '/repos/testOwner/testRepo/pulls/12/files?per_page=100' ) . reply ( 200 , [ { filename : `.github/${ helper . CONFIG_FILE_NAME }` , sha : 'testsha' , } , ] ) . get ( '/repos/testOwner/testRepo/git/blobs/testsha' ) . reply ( 200 , createConfigResponse ( configFile ) ) ; } describe ( 'getConfigWithDefault' , ( ) => { let probot ; let validateConfigStub ; let autoLabelOnPRStub ; beforeEach ( ( ) => { probot = createProbot ( { overrides : { githubToken : 'abc123' , Octokit : ProbotOctokit . defaults ( { retry : { enabled : false } , throttle : { enabled : false } , } ) , } , } ) ; probot . load ( handler ) ; validateConfigStub = sandbox . stub ( ConfigChecker . prototype , 'validateConfigChanges' ) ; validateConfigStub . resolves ( ) ; autoLabelOnPRStub = sandbox . stub ( handler , 'autoLabelOnPR' ) ; } ) ; afterEach ( ( ) => { nock . cleanAll ( ) ; sandbox . restore ( ) ; } ) ; describe ( 'compatibility tests' , ( ) => { it ( 'fetches a simple config correctly' , async ( ) => { const scope = fetchConfig ( 'valid-config.yml' ) ; const payload = require ( resolve ( fixturesPath , './events/pr_opened' ) ) ; await probot . receive ( { name : 'pull_request' , payload , id : 'abc123' , } ) ; scope . done ( ) ; sinon . assert . calledOnceWithExactly ( validateConfigStub , sinon . match . instanceOf ( ProbotOctokit ) , 'testOwner' , 'testRepo' , '19f6a66851125917fa07615dcbc0cd13dad56981' , 12 ) ; sinon . assert . calledOnceWithExactly ( autoLabelOnPRStub , sinon . match . instanceOf ( Context ) , 'testOwner' , 'testRepo' , sinon . match . any ) ; const config = autoLabelOnPRStub . getCall ( 0 ) . args [ 3 ] ; assert . strictEqual ( config . product , true ) ; } ) ; it ( 'fetches a real world config correctly(cloud-ops-sandbox)' , async ( ) => { const scope = fetchConfig ( 'cloud-ops-sandbox.yml' ) ; const payload = require ( resolve ( fixturesPath , './events/pr_opened' ) ) ; await probot . receive ( { name : 'pull_request' , payload , id : 'abc123' , } ) ; scope . done ( ) ; sinon . assert . calledOnceWithExactly ( validateConfigStub , sinon . match . instanceOf ( ProbotOctokit ) , 'testOwner' , 'testRepo' , '19f6a66851125917fa07615dcbc0cd13dad56981' , 12 ) ; sinon . assert . calledOnceWithExactly ( autoLabelOnPRStub , sinon . match . instanceOf ( Context ) , 'testOwner' , 'testRepo' , sinon . match . any ) ; const config = autoLabelOnPRStub . getCall ( 0 ) . args [ 3 ] ; assert . strictEqual ( config . product , false ) ; assert . strictEqual ( config . path . pullrequest , false ) ; assert . strictEqual ( config . language . paths . src . frontend , 'go' ) ; assert . strictEqual ( config . language . paths . tests [ '.' ] , 'python' ) ; assert . strictEqual ( config . language . paths . website [ '.' ] , 'javascript' ) ; assert . strictEqual ( config . language . paths . website . images , 'svg' ) ; assert . strictEqual ( config . language . pullrequest , true ) ; assert . strictEqual ( config . language . labelprefix , 'lang: ' ) ; assert . strictEqual ( config . language . extensions . manifest [ 0 ] , 'tf' ) ; assert . strictEqual ( config . language . extensions . typescript [ 0 ] , 'ts' ) ; } ) ; } ) ; } ) ; describe ( 'validateConfigChanges' , ( ) => { let probot ; let getConfigWithDefaultStub ; let autoLabelOnPRStub ; beforeEach ( ( ) => { probot = createProbot ( { overrides : { githubToken : 'abc123' , Octokit : ProbotOctokit . defaults ( { retry : { enabled : false } , throttle : { enabled : false } , } ) , } , } ) ; probot . load ( handler ) ; getConfigWithDefaultStub = sandbox . stub ( botConfigModule , 'getConfigWithDefault' ) ; getConfigWithDefaultStub . resolves ( helper . DEFAULT_CONFIGS ) ; autoLabelOnPRStub = sandbox . stub ( handler , 'autoLabelOnPR' ) ; } ) ; afterEach ( ( ) => { nock . cleanAll ( ) ; sandbox . restore ( ) ; } ) ; describe ( 'compatibility tests' , ( ) => { it ( 'does not create a failing status check for a correct config' , async ( ) => { const scope = fetchFilesInPR ( 'cloud-ops-sandbox.yml' ) ; const payload = require ( resolve ( fixturesPath , './events/pr_opened' ) ) ; await probot . receive ( { name : 'pull_request' , payload , id : 'abc123' , } ) ; scope . done ( ) ; sinon . assert . calledOnceWithExactly ( autoLabelOnPRStub , sinon . match . instanceOf ( Context ) , 'testOwner' , 'testRepo' , sinon . match . any ) ; } ) ; it ( 'creates a failing status check for a correct config' , async ( ) => { const scope = fetchFilesInPR ( 'cloud-ops-sandbox-broken.yml' ) ; const payload = require ( resolve ( fixturesPath , './events/pr_opened' ) ) ; scope . post ( '/repos/testOwner/testRepo/check-runs' , body => { snapshot ( body ) ; return true ; } ) . reply ( 200 ) ; await probot . receive ( { name : 'pull_request' , payload , id : 'abc123' , } ) ; scope . done ( ) ; sinon . assert . calledOnceWithExactly ( autoLabelOnPRStub , sinon . match . instanceOf ( Context ) , 'testOwner' , 'testRepo' , sinon . match . any ) ; } ) ; } ) ; } ) ;