import { expect } from 'chai'; import sinon from 'sinon'; import oss from '../../src/oss'; import certificate from '../../src/certificate'; import {listFiles, uploadReport} from '../../src/testCase/uploadReport' import path from 'path'; import * as fs from 'fs' import * as glob from 'glob'; describe('uploadReport Function', () => { const sandbox = sinon.createSandbox(); const mockEndpoint = 'mock-endpoint'; const mockFlowJobToken = 'mock-token'; const mockCertificate = { accessKeyId: 'mock-access-key-id', accessKeySecret: 'mock-access-key-secret', securityToken: 'mock-security-token', bucketName: 'mock-bucket-name', ossPathPrefix: 'mock/oss/path' }; let getOssRamStsCertificateStub: sinon.SinonStub let uploadStub: sinon.SinonStub; let globStub: sinon.SinonStub; let sizeCheckStub: sinon.SinonStub; beforeEach(() => { process.env['endpoint'] = mockEndpoint; process.env['FLOW_JOB_TOKEN'] = mockFlowJobToken; process.env['PIPELINE_ID'] = 'mock-pipeline-id'; getOssRamStsCertificateStub = sandbox.stub(certificate, 'getOssRamStsCertificate').resolves(mockCertificate); uploadStub = sandbox.stub(oss, 'upload').resolves(); globStub = sandbox.stub(glob, 'glob'); // eslint-disable-next-line @typescript-eslint/no-var-requires sizeCheckStub = sandbox.stub(require('../../src/testCase/sizeCheck'), 'sizeCheck').resolves(); }); afterEach(() => { sandbox.restore(); }); it('should throw an error if FLOW_JOB_TOKEN is missing', async () => { const reportPath = 'path/to/report.txt'; delete process.env['FLOW_JOB_TOKEN']; try{ await uploadReport(reportPath); }catch (e:any){ expect(e.message).to.equal('missing FLOW_JOB_TOKEN'); } }); it('should upload report and return objectKey - non-html', async () => { const reportPath = 'path/to/report.txt'; const objectKey = await uploadReport(reportPath); expect(getOssRamStsCertificateStub.calledOnceWith(mockFlowJobToken, certificate.OssBucketType.ASSETS)).to.be.true; expect(uploadStub.calledOnce).to.be.true; // Verify the object key format const reportIndex = path.basename(reportPath); // As UUID is dynamic, use a regex to match the expected format expect(objectKey).to.match(new RegExp(`^${mockCertificate.ossPathPrefix}/mock-pipeline-id/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/${reportIndex}$`)); }); it('should upload all files under directory and return objectKey - html', async () => { const reportPath = 'path/to/report.html'; globStub.resolves(['report.html','image.png','css/t1.css','css/t2.css']) const objectKey = await uploadReport(reportPath); expect(getOssRamStsCertificateStub.calledOnceWith(mockFlowJobToken, certificate.OssBucketType.ASSETS)).to.be.true; expect(uploadStub.calledWith(sinon.match.any,'path/to/report.html',sinon.match.any,sinon.match.any)).to.be.true; expect(uploadStub.calledWith(sinon.match.any,'path/to/image.png',sinon.match.any,sinon.match.any)).to.be.true; expect(uploadStub.calledWith(sinon.match.any,'path/to/css/t1.css',sinon.match.any,sinon.match.any)).to.be.true; expect(uploadStub.calledWith(sinon.match.any,'path/to/css/t2.css',sinon.match.any,sinon.match.any)).to.be.true; // Verify the object key format const reportIndex = path.basename(reportPath); // As UUID is dynamic, use a regex to match the expected format expect(objectKey).to.match(new RegExp(`^${mockCertificate.ossPathPrefix}/mock-pipeline-id/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/${reportIndex}$`)); }); }); describe('listFiles Function', () => { const testDir = './testDir'; before(() => { fs.mkdirSync(testDir); }); after(() => { fs.rmSync(testDir, { recursive: true, force: true }); }); it('should list files under the directory', async () => { fs.writeFileSync(path.join(testDir, 'file1.txt'), 'Hello, world!'); fs.writeFileSync(path.join(testDir, 'file2.txt'), 'Another file'); const subDir = path.join(testDir, 'subDir'); fs.mkdirSync(subDir); fs.writeFileSync(path.join(subDir, 'file3.txt'), '3rd file'); const files = await listFiles(testDir); expect(files).to.deep.equal(['file2.txt', 'file1.txt', 'subDir/file3.txt']); }) })