diff --git a/tests/git/http.test.ts b/tests/git/http.test.ts index 5ca2d016bb..aed4efddf5 100644 --- a/tests/git/http.test.ts +++ b/tests/git/http.test.ts @@ -1,4 +1,3 @@ -import type { POJO } from '@'; import fs from 'fs'; import path from 'path'; import os from 'os'; @@ -8,7 +7,6 @@ import { test } from '@fast-check/jest'; import fc from 'fast-check'; import * as gitHttp from '@/git/http'; import * as validationErrors from '@/validation/errors'; -import * as utils from '@/utils'; import * as gitTestUtils from './utils'; describe('Git Http', () => { @@ -298,46 +296,7 @@ describe('Git Http', () => { ], }); - const request = async function ({ - url, - method = 'GET', - headers = {}, - body = [Buffer.from('')], - }: { - url: string; - method: string; - headers: POJO; - body: Array; - }) { - if (method === 'GET') { - // Send back the GET request info response - const advertiseRefGen = gitHttp.advertiseRefGenerator(gitDirs); - - return { - url: url, - method: method, - body: advertiseRefGen, - headers: headers, - statusCode: 200, - statusMessage: 'OK', - }; - } else if (method === 'POST') { - const packGen = gitHttp.generatePackRequest({ - ...gitDirs, - body, - }); - return { - url: url, - method: method, - body: packGen, - headers: headers, - statusCode: 200, - statusMessage: 'OK', - }; - } else { - utils.never(); - } - }; + const request = gitTestUtils.request(gitDirs); const newDir = path.join(dataDir, 'newRepo'); const newDirs = { fs, @@ -360,4 +319,96 @@ describe('Git Http', () => { (await fs.promises.readFile(path.join(newDirs.dir, 'file2'))).toString(), ).toBe('this is another file'); }); + test('end to end Pull', async () => { + await gitTestUtils.createGitRepo({ + ...gitDirs, + author: 'tester', + commits: [ + { + message: 'commit1', + files: [ + { + name: 'file1', + contents: 'this is a file', + }, + ], + }, + { + message: 'commit2', + files: [ + { + name: 'file2', + contents: 'this is another file', + }, + ], + }, + { + message: 'commit3', + files: [ + { + name: 'file1', + contents: 'this is a changed file', + }, + ], + }, + ], + }); + const newDir = path.join(dataDir, 'newRepo'); + const newDirs = { + fs, + dir: newDir, + gitdir: path.join(newDir, '.git'), + gitDir: path.join(newDir, '.git'), + }; + const request = gitTestUtils.request(gitDirs); + await git.clone({ + fs, + dir: newDir, + http: { request }, + url: 'http://', + }); + // Add more history + await gitTestUtils.createGitRepo({ + ...gitDirs, + init: false, + author: 'tester', + commits: [ + { + message: 'commit4', + files: [ + { + name: 'file3', + contents: 'this is another file3', + }, + ], + }, + ], + }); + await git.pull({ + ...newDirs, + http: { request }, + url: 'http://', + ref: 'HEAD', + singleBranch: true, + fastForward: true, + fastForwardOnly: true, + author: { + name: 'asd', + }, + }); + // After pulling, we expect the new repo to include all history from the old + const logOld = ( + await git.log({ + ...gitDirs, + ref: 'HEAD', + }) + ).map((v) => v.oid); + const logNew = ( + await git.log({ + ...newDirs, + ref: 'HEAD', + }) + ).map((v) => v.oid); + expect(logNew).toIncludeAllMembers(logOld); + }); }); diff --git a/tests/git/utils.ts b/tests/git/utils.ts index 9172ffea51..e3b2590a4a 100644 --- a/tests/git/utils.ts +++ b/tests/git/utils.ts @@ -1,4 +1,4 @@ -import type { FileSystem } from '@'; +import type { FileSystem, POJO } from '@'; import type { CapabilityList } from '@/git/types'; import type { Arbitrary } from 'fast-check'; import type fs from 'fs'; @@ -7,7 +7,7 @@ import git from 'isomorphic-git'; import fc from 'fast-check'; import * as gitUtils from '@/git/utils'; import * as gitHttp from '@/git/http'; -import { never } from '@/utils'; +import * as utils from '@/utils'; // Just to avoid confusing the type with the name type FsType = typeof fs; @@ -21,6 +21,7 @@ async function createGitRepo({ gitdir, author, commits, + init = true, }: { fs: FsType; dir: string; @@ -30,6 +31,7 @@ async function createGitRepo({ message: string; files: Array<{ name: string; contents: string }>; }>; + init?: boolean; }) { const gitDirs = { fs, @@ -46,9 +48,11 @@ async function createGitRepo({ email: `${author}@test.com`, }, }; - await git.init({ - ...gitDirs, - }); + if (init) { + await git.init({ + ...gitDirs, + }); + } for (const { message, files } of commits) { await Promise.all( files.map(({ name, contents }) => @@ -140,7 +144,7 @@ function generateTestNegotiationLine(data: NegotiationTestData, rest: Buffer) { case 'none': return Buffer.alloc(0); default: - never(); + utils.never(); } } @@ -157,6 +161,67 @@ async function* tapGen( console.log(acc); } +/** + * Create a test request handler for use with `git.clone` and `git.pull` + */ +function request({ + fs, + dir, + gitDir, +}: { + fs: any; + dir: string; + gitDir: string; +}) { + return async ({ + url, + method = 'GET', + headers = {}, + body = [Buffer.from('')], + }: { + url: string; + method: string; + headers: POJO; + body: Array; + }) => { + // Console.log('body', body.map(v => v.toString())) + if (method === 'GET') { + // Send back the GET request info response + const advertiseRefGen = gitHttp.advertiseRefGenerator({ + fs, + dir, + gitDir, + }); + + return { + url: url, + method: method, + body: advertiseRefGen, + headers: headers, + statusCode: 200, + statusMessage: 'OK', + }; + } else if (method === 'POST') { + const packGen = gitHttp.generatePackRequest({ + fs, + dir, + gitDir, + body, + }); + return { + url: url, + method: method, + body: packGen, + headers: headers, + statusCode: 200, + statusMessage: 'OK', + }; + } else { + utils.never(); + } + }; +} + const objectIdArb = fc.hexaString({ maxLength: 40, minLength: 40, @@ -194,6 +259,7 @@ export { listGitObjects, generateTestNegotiationLine, tapGen, + request, objectIdArb, capabilityArb, capabilityListArb,