diff --git a/plugins/techdocs-node/__mocks__/@google-cloud/storage.ts b/plugins/techdocs-node/__mocks__/@google-cloud/storage.ts deleted file mode 100644 index e87ccb69c1..0000000000 --- a/plugins/techdocs-node/__mocks__/@google-cloud/storage.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Readable } from 'stream'; -import { IStorageFilesMock } from '../../src/testUtils/types'; - -const storage = global.storageFilesMock as IStorageFilesMock; - -class GCSFile { - private readonly path: string; - - constructor(path: string) { - this.path = path; - } - - exists() { - return new Promise(async (resolve, reject) => { - if (storage.fileExists(this.path)) { - resolve([true]); - } else { - reject(); - } - }); - } - - createReadStream() { - const readable = new Readable(); - readable._read = () => {}; - - process.nextTick(() => { - if (storage.fileExists(this.path)) { - if (readable.eventNames().includes('pipe')) { - readable.emit('pipe'); - } - readable.emit('data', storage.readFile(this.path)); - readable.emit('end'); - } else { - readable.emit( - 'error', - new Error(`The file ${this.path} does not exist!`), - ); - } - }); - - return readable; - } - - delete() { - return Promise.resolve(); - } -} - -class Bucket { - private readonly bucketName; - - constructor(bucketName: string) { - this.bucketName = bucketName; - } - - async getMetadata() { - if (this.bucketName === 'bad_bucket_name') { - throw Error('Bucket does not exist'); - } - return ''; - } - - upload(source: string, { destination }) { - return new Promise(async resolve => { - storage.writeFile(destination, source); - resolve(null); - }); - } - - file(destinationFilePath: string) { - if (this.bucketName === 'delete_stale_files_error') { - throw Error('Message'); - } - return new GCSFile(destinationFilePath); - } - - getFilesStream() { - const readable = new Readable(); - readable._read = () => {}; - - process.nextTick(() => { - if ( - this.bucketName === 'delete_stale_files_success' || - this.bucketName === 'delete_stale_files_error' - ) { - readable.emit('data', { name: 'stale-file.png' }); - } - readable.emit('end'); - }); - - return readable; - } -} - -export class Storage { - constructor() { - storage.emptyFiles(); - } - - bucket(bucketName) { - return new Bucket(bucketName); - } -} diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts index 6471d89a06..b347f185c6 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts @@ -22,11 +22,119 @@ import request from 'supertest'; import mockFs from 'mock-fs'; import path from 'path'; import fs from 'fs-extra'; +import { Readable } from 'stream'; import { GoogleGCSPublish } from './googleStorage'; +import { + storageRootDir, + StorageFilesMock, +} from '../../testUtils/StorageFilesMock'; -// NOTE: /plugins/techdocs-node/__mocks__ is being used to mock Google Cloud Storage client library +jest.mock('@google-cloud/storage', () => { + class GCSFile { + constructor( + private readonly filePath: string, + private readonly storage: StorageFilesMock, + ) {} -const rootDir = (global as any).rootDir; // Set by setupTests.ts + exists() { + return new Promise(async (resolve, reject) => { + if (this.storage.fileExists(this.filePath)) { + resolve([true]); + } else { + reject(); + } + }); + } + + createReadStream() { + const readable = new Readable(); + readable._read = () => {}; + + process.nextTick(() => { + if (this.storage.fileExists(this.filePath)) { + if (readable.eventNames().includes('pipe')) { + readable.emit('pipe'); + } + readable.emit('data', this.storage.readFile(this.filePath)); + readable.emit('end'); + } else { + readable.emit( + 'error', + new Error(`The file ${this.filePath} does not exist!`), + ); + } + }); + + return readable; + } + + delete() { + return Promise.resolve(); + } + } + + class Bucket { + constructor( + private readonly bucketName: string, + private readonly storage: StorageFilesMock, + ) {} + + async getMetadata() { + if (this.bucketName === 'bad_bucket_name') { + throw Error('Bucket does not exist'); + } + return ''; + } + + upload(source: string, { destination }: { destination: string }) { + return new Promise(async resolve => { + this.storage.writeFile(destination, source); + resolve(null); + }); + } + + file(destinationFilePath: string) { + if (this.bucketName === 'delete_stale_files_error') { + throw Error('Message'); + } + return new GCSFile(destinationFilePath, this.storage); + } + + getFilesStream() { + const readable = new Readable(); + readable._read = () => {}; + + process.nextTick(() => { + if ( + this.bucketName === 'delete_stale_files_success' || + this.bucketName === 'delete_stale_files_error' + ) { + readable.emit('data', { name: 'stale-file.png' }); + } + readable.emit('end'); + }); + + return readable; + } + } + + class Storage { + storage = new StorageFilesMock(); + + constructor() { + this.storage.emptyFiles(); + } + + bucket(bucketName: string) { + return new Bucket(bucketName, this.storage); + } + } + + return { + __esModule: true, + Storage, + }; +}); const getEntityRootDir = (entity: Entity) => { const { @@ -34,7 +142,7 @@ const getEntityRootDir = (entity: Entity) => { metadata: { namespace, name }, } = entity; - return path.join(rootDir, namespace || DEFAULT_NAMESPACE, kind, name); + return path.join(storageRootDir, namespace || DEFAULT_NAMESPACE, kind, name); }; const logger = getVoidLogger(); @@ -193,7 +301,7 @@ describe('GoogleGCSPublish', () => { it('should fail to publish a directory', async () => { const wrongPathToGeneratedDirectory = path.join( - rootDir, + storageRootDir, 'wrong', 'path', 'to',