Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mirror-url parameter to allow downloading Node.js from a custom URL #1232

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Next Next commit
mirror-url -implementation
  • Loading branch information
aparnajyothi-y committed Feb 19, 2025
commit 1b0ef2d227f12ba775e9c8e90c6751970069d686
158 changes: 157 additions & 1 deletion __tests__/canary-installer.test.ts
Original file line number Diff line number Diff line change
@@ -10,13 +10,14 @@ import osm from 'os';
import path from 'path';
import * as main from '../src/main';
import * as auth from '../src/authutil';
import {INodeVersion} from '../src/distributions/base-models';
import {INodeVersion, NodeInputs} from '../src/distributions/base-models';

import nodeTestManifest from './data/versions-manifest.json';
import nodeTestDist from './data/node-dist-index.json';
import nodeTestDistNightly from './data/node-nightly-index.json';
import nodeTestDistRc from './data/node-rc-index.json';
import nodeV8CanaryTestDist from './data/v8-canary-dist-index.json';
import canaryBuild from '../src/distributions/v8-canary/canary_builds';

describe('setup-node', () => {
let inputs = {} as any;
@@ -528,4 +529,159 @@ describe('setup-node', () => {
expect(cacheSpy).not.toHaveBeenCalled();
});
});

describe('CanaryBuild - Mirror URL functionality', () => {
class CanaryBuild {
mirrorURL: string | undefined;
nodeInfo: NodeInputs;

constructor(nodeInfo: NodeInputs) {
this.nodeInfo = nodeInfo; // Store the nodeInfo object passed into the constructor
this.mirrorURL = nodeInfo.mirrorURL; // Set mirrorURL from nodeInfo, or undefined if not provided
}

async getDistributionMirrorUrl() {
// Check if mirror URL is undefined or empty, and return the default if so
if (!this.mirrorURL) {
core.info('Using mirror URL: https://nodejs.org/download/v8-canary');
return 'https://nodejs.org/download/v8-canary'; // Default URL
} else {
if (this.mirrorURL === '') {
throw new Error(
'Mirror URL is empty. Please provide a valid mirror URL.'
);
}
return this.mirrorURL;
}
}
}

it('should use the mirror URL from nodeInfo if provided', () => {
// Mocking core.info to track the log calls
const infoSpy = jest.spyOn(core, 'info').mockImplementation(() => {});

const mirrorURL = 'https://custom.mirror.url/v8-canary';
const nodeInfo: NodeInputs = {
versionSpec: '8.0.0-canary',
arch: 'x64',
checkLatest: false,
stable: false,
mirrorURL: mirrorURL // Provide the custom mirror URL
};

const canaryBuild = new CanaryBuild(nodeInfo);

// Call the method to get the mirror URL
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();

// Assert that core.info was called with the custom mirror URL
expect(infoSpy).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);

// Assert that the returned URL is the custom mirror URL
expect(distributionMirrorUrl).toBe(mirrorURL);

// Restore the original core.info implementation
infoSpy.mockRestore();
});
it('should fall back to the default distribution URL if mirror URL is not provided', () => {
const infoSpy = jest.spyOn(core, 'info').mockImplementation(() => {});

const nodeInfo: NodeInputs = {
versionSpec: '8.0.0-canary',
arch: 'x64',
checkLatest: false,
stable: false
// No mirrorURL provided here
};

const canaryBuild = new CanaryBuild(nodeInfo);

// Call the method to get the distribution URL
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();

// Assert that core.info was called with the default URL
expect(infoSpy).toHaveBeenCalledWith(
'Using mirror URL: https://nodejs.org/download/v8-canary'
);

// Assert that the returned URL is the default one
expect(distributionMirrorUrl).toBe(
'https://nodejs.org/download/v8-canary'
);

infoSpy.mockRestore();
});

it('should log the correct info when mirror URL is not provided', () => {
const infoSpy = jest.spyOn(core, 'info').mockImplementation(() => {});

const nodeInfo: NodeInputs = {
versionSpec: '8.0.0-canary',
arch: 'x64',
checkLatest: false,
stable: false
// No mirrorURL provided here
};

const canaryBuild = new CanaryBuild(nodeInfo);

// Call the method
canaryBuild.getDistributionMirrorUrl();

// Assert that core.info was called with the fallback URL
expect(infoSpy).toHaveBeenCalledWith(
'Using mirror URL: https://nodejs.org/download/v8-canary'
);

infoSpy.mockRestore();
});

it('should return mirror URL if provided in nodeInfo', () => {
// Custom mirror URL to be tested
const mirrorURL = 'https://custom.mirror.url/v8-canary';

// Create a spy on core.info to track its calls
const infoSpy = jest.spyOn(core, 'info').mockImplementation(() => {}); // Mocking core.info

// Prepare the nodeInfo object with the custom mirror URL
const nodeInfo: NodeInputs = {
versionSpec: '8.0.0-canary',
arch: 'x64',
mirrorURL: mirrorURL, // Custom mirrorURL provided
checkLatest: false,
stable: false
};

// Create an instance of CanaryBuild, passing nodeInfo to the constructor
const canaryBuild = new CanaryBuild(nodeInfo);

// Call the method
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();

// Assert that core.info was called with the expected message
expect(infoSpy).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);

// Assert that the returned mirror URL is correct
expect(distributionMirrorUrl).toBe(mirrorURL);

// Restore the original core.info function after the test
infoSpy.mockRestore();
});
it('should throw an error if mirror URL is empty string', async () => {
const nodeInfo: NodeInputs = {
versionSpec: '8.0.0-canary',
arch: 'x64',
checkLatest: false,
stable: false,
mirrorURL: '' // Empty string provided as mirror URL
};

const canaryBuild = new CanaryBuild(nodeInfo);

// Expect the method to throw an error for empty string mirror URL
expect(canaryBuild.getDistributionMirrorUrl()).toThrow(
'Mirror URL is empty. Please provide a valid mirror URL.'
);
});
});
});
95 changes: 95 additions & 0 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as core from '@actions/core';
import 'jest';
import * as exec from '@actions/exec';
import * as tc from '@actions/tool-cache';
import * as cache from '@actions/cache';
@@ -14,6 +15,11 @@ import * as main from '../src/main';
import * as util from '../src/util';
import OfficialBuilds from '../src/distributions/official_builds/official_builds';

import * as installerFactory from '../src/distributions/installer-factory';
jest.mock('../src/distributions/installer-factory', () => ({
getNodejsDistribution: jest.fn()
}));

describe('main tests', () => {
let inputs = {} as any;
let os = {} as any;
@@ -280,4 +286,93 @@ describe('main tests', () => {
);
});
});

// Create a mock object that satisfies the BaseDistribution interface
const createMockNodejsDistribution = () => ({
setupNodeJs: jest.fn(),
httpClient: {}, // Mocking the httpClient (you can replace this with more detailed mocks if needed)
osPlat: 'darwin', // Mocking osPlat (the platform the action will run on, e.g., 'darwin', 'win32', 'linux')
nodeInfo: {
version: '14.x',
arch: 'x64',
platform: 'darwin'
},
getDistributionUrl: jest.fn().mockReturnValue('https://nodejs.org/dist/'), // Example URL
install: jest.fn(),
validate: jest.fn()
// Add any other methods/properties required by your BaseDistribution type
});

describe('Mirror URL Tests', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should pass mirror URL correctly when provided', async () => {
jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'mirror-url') return 'https://custom-mirror-url.com';
if (name === 'node-version') return '14.x';
return '';
});

const mockNodejsDistribution = createMockNodejsDistribution();
(installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(
mockNodejsDistribution
);

await main.run();

// Ensure setupNodeJs is called with the correct parameters, including the mirror URL
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith({
versionSpec: '14.x',
checkLatest: false,
auth: undefined,
stable: true,
arch: 'x64',
mirrorURL: 'https://custom-mirror-url.com' // Ensure this matches
});
});

it('should use default mirror URL when no mirror URL is provided', async () => {
jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'mirror-url') return ''; // Simulating no mirror URL provided
if (name === 'node-version') return '14.x';
return '';
});

const mockNodejsDistribution = createMockNodejsDistribution();
(installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(
mockNodejsDistribution
);

await main.run();

// Expect that setupNodeJs is called with an empty mirror URL (default behavior)
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(
expect.objectContaining({
mirrorURL: '' // Default URL is expected to be handled internally
})
);
});

it('should handle mirror URL with spaces correctly', async () => {
const mirrorURL = 'https://custom-mirror-url.com ';
const expectedTrimmedURL = 'https://custom-mirror-url.com';

// Mock the setupNodeJs function
const mockNodejsDistribution = {
setupNodeJs: jest.fn()
};

// Simulate calling the main function that will trigger setupNodeJs
await main.run();

// Assert that setupNodeJs was called with the correct trimmed mirrorURL
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(
expect.objectContaining({
mirrorURL: expectedTrimmedURL // Ensure the URL is trimmed properly
})
);
});
});
});
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.