mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
229 lines
8.2 KiB
TypeScript
229 lines
8.2 KiB
TypeScript
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
import { assert } from 'chai';
|
|
|
|
import { AdvertisementUtils } from '../../../src/utils/AdvertisementUtils';
|
|
import { Utils } from '../../../src/utils/Utils';
|
|
|
|
const envPaths = Utils.nodeRequire('env-paths').default;
|
|
|
|
describe('AdvertisementUtils', () => {
|
|
const configPath = path.join(envPaths('javascript-obfuscator').config, 'config.json');
|
|
|
|
function readConfig(): any {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function writeConfig(data: any): void {
|
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
fs.writeFileSync(configPath, JSON.stringify(data));
|
|
}
|
|
|
|
function deleteConfig(): void {
|
|
try {
|
|
fs.unlinkSync(configPath);
|
|
} catch {
|
|
// Ignore
|
|
}
|
|
}
|
|
|
|
describe('isCI', () => {
|
|
const originalEnv = { ...process.env };
|
|
|
|
afterEach(() => {
|
|
// Restore original environment
|
|
process.env = { ...originalEnv };
|
|
});
|
|
|
|
describe('Variant #1: CI environment variable set', () => {
|
|
it('should return true when CI=true', () => {
|
|
process.env.CI = 'true';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return true when CI=1', () => {
|
|
process.env.CI = '1';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return true when GITHUB_ACTIONS is set', () => {
|
|
process.env.GITHUB_ACTIONS = 'true';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return true when TRAVIS is set', () => {
|
|
process.env.TRAVIS = 'true';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return true when GITLAB_CI is set', () => {
|
|
process.env.GITLAB_CI = 'true';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return true when JENKINS_URL is set', () => {
|
|
process.env.JENKINS_URL = 'http://jenkins.example.com';
|
|
assert.isTrue(AdvertisementUtils.isCI());
|
|
});
|
|
});
|
|
|
|
describe('Variant #2: CI environment variable not set or false', () => {
|
|
beforeEach(() => {
|
|
// Clear all CI-related env vars
|
|
delete process.env.CI;
|
|
delete process.env.CONTINUOUS_INTEGRATION;
|
|
delete process.env.GITHUB_ACTIONS;
|
|
delete process.env.GITLAB_CI;
|
|
delete process.env.TRAVIS;
|
|
delete process.env.CIRCLECI;
|
|
delete process.env.JENKINS_URL;
|
|
delete process.env.BUILDKITE;
|
|
delete process.env.TF_BUILD;
|
|
});
|
|
|
|
it('should return false when no CI env vars are set', () => {
|
|
assert.isFalse(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return false when CI=false', () => {
|
|
process.env.CI = 'false';
|
|
assert.isFalse(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return false when CI=0', () => {
|
|
process.env.CI = '0';
|
|
assert.isFalse(AdvertisementUtils.isCI());
|
|
});
|
|
|
|
it('should return false when CI is empty string', () => {
|
|
process.env.CI = '';
|
|
assert.isFalse(AdvertisementUtils.isCI());
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('shouldShowAdvertisement', () => {
|
|
const originalEnv = { ...process.env };
|
|
const originalIsTTY = process.stdout.isTTY;
|
|
|
|
afterEach(() => {
|
|
process.env = { ...originalEnv };
|
|
process.stdout.isTTY = originalIsTTY;
|
|
});
|
|
|
|
describe('Variant #1: non-TTY environment', () => {
|
|
it('should return false when stdout is not a TTY', () => {
|
|
process.stdout.isTTY = false;
|
|
// Clear CI env vars
|
|
delete process.env.CI;
|
|
assert.isFalse(AdvertisementUtils.shouldShowAdvertisement());
|
|
});
|
|
});
|
|
|
|
describe('Variant #2: CI environment', () => {
|
|
it('should return false in CI environment', () => {
|
|
process.stdout.isTTY = true;
|
|
process.env.CI = 'true';
|
|
assert.isFalse(AdvertisementUtils.shouldShowAdvertisement());
|
|
});
|
|
});
|
|
|
|
describe('Variant #3: display counter and reset', () => {
|
|
beforeEach(() => {
|
|
deleteConfig();
|
|
// Reset cached config path
|
|
(AdvertisementUtils as any).configPath = null;
|
|
// Ensure TTY and non-CI environment
|
|
process.stdout.isTTY = true;
|
|
delete process.env.CI;
|
|
delete process.env.GITHUB_ACTIONS;
|
|
delete process.env.TRAVIS;
|
|
delete process.env.GITLAB_CI;
|
|
});
|
|
|
|
afterEach(() => {
|
|
deleteConfig();
|
|
(AdvertisementUtils as any).configPath = null;
|
|
});
|
|
|
|
it('should return true for first 5 calls', () => {
|
|
for (let i = 0; i < 5; i++) {
|
|
assert.isTrue(AdvertisementUtils.shouldShowAdvertisement(), `Call ${i + 1} should return true`);
|
|
}
|
|
});
|
|
|
|
it('should return false after 5 calls', () => {
|
|
// Exhaust the counter
|
|
for (let i = 0; i < 5; i++) {
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
}
|
|
|
|
// 6th call should return false
|
|
assert.isFalse(AdvertisementUtils.shouldShowAdvertisement());
|
|
});
|
|
|
|
it('should increment counter on each call', () => {
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
assert.strictEqual(readConfig().adDisplayCount, 1);
|
|
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
assert.strictEqual(readConfig().adDisplayCount, 2);
|
|
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
assert.strictEqual(readConfig().adDisplayCount, 3);
|
|
});
|
|
|
|
it('should set first display timestamp on first call', () => {
|
|
const beforeTime = Date.now();
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
const afterTime = Date.now();
|
|
|
|
const timestamp = readConfig().adFirstDisplayTime;
|
|
assert.isNumber(timestamp);
|
|
assert.isAtLeast(timestamp, beforeTime);
|
|
assert.isAtMost(timestamp, afterTime);
|
|
});
|
|
|
|
it('should reset counter after 3 days', () => {
|
|
// Exhaust counter
|
|
for (let i = 0; i < 5; i++) {
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
}
|
|
assert.isFalse(AdvertisementUtils.shouldShowAdvertisement());
|
|
|
|
// Simulate 3 days passing by setting old timestamp
|
|
const threeDaysAgo = Date.now() - 3 * 24 * 60 * 60 * 1000 - 1000;
|
|
const data = readConfig();
|
|
data.adFirstDisplayTime = threeDaysAgo;
|
|
writeConfig(data);
|
|
|
|
// Should return true again after reset
|
|
assert.isTrue(AdvertisementUtils.shouldShowAdvertisement());
|
|
// Counter should be reset to 1
|
|
assert.strictEqual(readConfig().adDisplayCount, 1);
|
|
});
|
|
|
|
it('should not reset counter before 3 days', () => {
|
|
// Exhaust counter
|
|
for (let i = 0; i < 5; i++) {
|
|
AdvertisementUtils.shouldShowAdvertisement();
|
|
}
|
|
|
|
// Simulate 2 days passing (less than 3 days)
|
|
const twoDaysAgo = Date.now() - 2 * 24 * 60 * 60 * 1000;
|
|
const data = readConfig();
|
|
data.adFirstDisplayTime = twoDaysAgo;
|
|
writeConfig(data);
|
|
|
|
// Should still return false
|
|
assert.isFalse(AdvertisementUtils.shouldShowAdvertisement());
|
|
});
|
|
});
|
|
});
|
|
});
|