Skip to content

Commit 99e142b

Browse files
Update test suite
1 parent 62c4697 commit 99e142b

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

packages/nextjs/src/__tests__/keyless-custom-headers.test.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ describe('keyless-custom-headers', () => {
134134
xPort: '3000',
135135
xProtocol: 'https',
136136
xClerkAuthStatus: 'signed-out',
137+
isCI: true,
137138
};
138139

139140
const result = formatMetadataHeaders(metadata);
@@ -149,6 +150,7 @@ describe('keyless-custom-headers', () => {
149150
expect(result.get('Clerk-X-Port')).toBe('3000');
150151
expect(result.get('Clerk-X-Protocol')).toBe('https');
151152
expect(result.get('Clerk-Auth-Status')).toBe('signed-out');
153+
expect(result.get('Clerk-Is-CI')).toBe('true');
152154
});
153155

154156
it('should handle missing optional fields gracefully', () => {
@@ -159,6 +161,7 @@ describe('keyless-custom-headers', () => {
159161
xPort: '3000',
160162
xProtocol: 'https',
161163
xClerkAuthStatus: 'signed-out',
164+
isCI: false,
162165
// Missing: nodeVersion, nextVersion, npmConfigUserAgent, port
163166
};
164167

@@ -177,6 +180,7 @@ describe('keyless-custom-headers', () => {
177180
expect(result.get('Clerk-Next-Version')).toBeNull();
178181
expect(result.get('Clerk-NPM-Config-User-Agent')).toBeNull();
179182
expect(result.get('Clerk-Node-Port')).toBeNull();
183+
expect(result.get('Clerk-Is-CI')).toBeNull();
180184
});
181185

182186
it('should handle undefined values for optional fields', () => {
@@ -191,6 +195,7 @@ describe('keyless-custom-headers', () => {
191195
xPort: 'test-x-port',
192196
xProtocol: 'test-x-protocol',
193197
xClerkAuthStatus: 'test-auth-status',
198+
isCI: false,
194199
};
195200

196201
const result = formatMetadataHeaders(metadata);
@@ -208,6 +213,7 @@ describe('keyless-custom-headers', () => {
208213
expect(result.get('Clerk-X-Port')).toBe('test-x-port');
209214
expect(result.get('Clerk-X-Protocol')).toBe('test-x-protocol');
210215
expect(result.get('Clerk-Auth-Status')).toBe('test-auth-status');
216+
expect(result.get('Clerk-Is-CI')).toBeNull();
211217
});
212218

213219
it('should handle empty string values', () => {
@@ -222,6 +228,7 @@ describe('keyless-custom-headers', () => {
222228
xPort: '',
223229
xProtocol: '',
224230
xClerkAuthStatus: '',
231+
isCI: false,
225232
};
226233

227234
const result = formatMetadataHeaders(metadata);
@@ -237,6 +244,7 @@ describe('keyless-custom-headers', () => {
237244
expect(result.get('Clerk-X-Port')).toBeNull();
238245
expect(result.get('Clerk-X-Protocol')).toBeNull();
239246
expect(result.get('Clerk-Auth-Status')).toBeNull();
247+
expect(result.get('Clerk-Is-CI')).toBeNull();
240248
});
241249
});
242250

@@ -334,6 +342,7 @@ describe('keyless-custom-headers', () => {
334342
xHost: 'example.com',
335343
xProtocol: 'https',
336344
xClerkAuthStatus: 'signed-out',
345+
isCI: false,
337346
});
338347

339348
// Restore original values
@@ -419,6 +428,88 @@ describe('keyless-custom-headers', () => {
419428
expect(result.xHost).toBe('forwarded-test-host.example.com');
420429
expect(result.xProtocol).toBe('https');
421430
});
431+
432+
it('should detect CI environment with truthy values', async () => {
433+
const truthyValues = ['1', 'true', '0.1'];
434+
const ciPlatforms = ['CI', 'GITHUB_ACTIONS', 'VERCEL'];
435+
436+
for (const platform of ciPlatforms) {
437+
for (const value of truthyValues) {
438+
vi.unstubAllEnvs();
439+
vi.stubEnv(platform, value);
440+
441+
// Recreate headers mock for each iteration to avoid state pollution
442+
mockHeaders.mockImplementation(async () => createMockHeaders());
443+
444+
const result = await collectKeylessMetadata();
445+
expect(result.isCI).toBe(true);
446+
}
447+
}
448+
});
449+
450+
it('should not detect CI environment with falsy values', async () => {
451+
const falsyValues = ['0', 'false', ''];
452+
const ciPlatforms = ['CI', 'GITHUB_ACTIONS'];
453+
454+
for (const platform of ciPlatforms) {
455+
for (const value of falsyValues) {
456+
vi.unstubAllEnvs();
457+
vi.stubEnv(platform, value);
458+
459+
// Recreate headers mock for each iteration to avoid state pollution
460+
mockHeaders.mockImplementation(async () => createMockHeaders());
461+
462+
const result = await collectKeylessMetadata();
463+
expect(result.isCI).toBe(false);
464+
}
465+
}
466+
});
467+
468+
it('should not detect CI environment when no CI indicators are present', async () => {
469+
// Clear all CI-related environment variables
470+
vi.stubEnv('CI', undefined);
471+
vi.stubEnv('GITHUB_ACTIONS', undefined);
472+
vi.stubEnv('VERCEL', undefined);
473+
vi.stubEnv('NETLIFY', undefined);
474+
vi.stubEnv('CIRCLECI', undefined);
475+
vi.stubEnv('TRAVIS', undefined);
476+
vi.stubEnv('JENKINS_URL', undefined);
477+
478+
const result = await collectKeylessMetadata();
479+
480+
expect(result.isCI).toBe(false);
481+
});
482+
483+
it('should only add Clerk-Is-CI header when isCI is true', () => {
484+
const metadataWithCI = {
485+
userAgent: 'test-user-agent',
486+
host: 'test-host',
487+
xHost: 'test-x-host',
488+
xPort: 'test-x-port',
489+
xProtocol: 'test-x-protocol',
490+
xClerkAuthStatus: 'test-auth-status',
491+
isCI: true,
492+
};
493+
494+
const metadataWithoutCI = {
495+
userAgent: 'test-user-agent',
496+
host: 'test-host',
497+
xHost: 'test-x-host',
498+
xPort: 'test-x-port',
499+
xProtocol: 'test-x-protocol',
500+
xClerkAuthStatus: 'test-auth-status',
501+
isCI: false,
502+
};
503+
504+
const resultWithCI = formatMetadataHeaders(metadataWithCI);
505+
const resultWithoutCI = formatMetadataHeaders(metadataWithoutCI);
506+
507+
// When isCI is true, header should be set to 'true'
508+
expect(resultWithCI.get('Clerk-Is-CI')).toBe('true');
509+
510+
// When isCI is false, header should not be set
511+
expect(resultWithoutCI.get('Clerk-Is-CI')).toBeNull();
512+
});
422513
});
423514

424515
it('should format metadata collected from collectKeylessMetadata correctly', async () => {
@@ -475,5 +566,67 @@ describe('keyless-custom-headers', () => {
475566
expect(headers.get('Clerk-X-Protocol')).toBe('https');
476567
expect(headers.get('Clerk-Auth-Status')).toBe('integration-status');
477568
expect(headers.get('Clerk-NPM-Config-User-Agent')).toBe('test-npm-agent');
569+
expect(headers.get('Clerk-Is-CI')).toBeNull(); // Should be null when no CI environment is detected
570+
});
571+
572+
it('should format metadata with CI environment detected correctly', async () => {
573+
// Reset mock to ensure clean state from previous test
574+
mockHeaders.mockReset();
575+
576+
// Setup environment with CI detection
577+
vi.stubEnv('PORT', '4000');
578+
vi.stubEnv('npm_config_user_agent', 'test-npm-agent');
579+
vi.stubEnv('CI', '1'); // Set CI environment variable
580+
581+
const mockHeaderStore = new Headers({
582+
'User-Agent': 'Integration-Test-Agent',
583+
host: 'localhost:4000',
584+
'x-forwarded-port': '4000',
585+
'x-forwarded-host': 'integration-forwarded-host',
586+
'x-forwarded-proto': 'https',
587+
'x-clerk-auth-status': 'integration-status',
588+
});
589+
590+
mockHeaders.mockResolvedValue({
591+
get: (key: string) => mockHeaderStore.get(key) || null,
592+
has: (key: string) => mockHeaderStore.has(key),
593+
forEach: () => {},
594+
entries: function* () {
595+
const headerEntries: [string, string][] = [];
596+
mockHeaderStore.forEach((value, key) => headerEntries.push([key, value]));
597+
for (const entry of headerEntries) {
598+
yield entry;
599+
}
600+
},
601+
keys: function* () {
602+
const headerKeys: string[] = [];
603+
mockHeaderStore.forEach((_, key) => headerKeys.push(key));
604+
for (const key of headerKeys) {
605+
yield key;
606+
}
607+
},
608+
values: function* () {
609+
const headerValues: string[] = [];
610+
mockHeaderStore.forEach(value => headerValues.push(value));
611+
for (const value of headerValues) {
612+
yield value;
613+
}
614+
},
615+
} as MockHeaders);
616+
617+
// Collect metadata and format headers
618+
const metadata = await collectKeylessMetadata();
619+
const headers = formatMetadataHeaders(metadata);
620+
621+
// Verify the full pipeline works correctly with CI detection
622+
expect(headers.get('Clerk-Client-User-Agent')).toBe('Integration-Test-Agent');
623+
expect(headers.get('Clerk-Client-Host')).toBe('localhost:4000');
624+
expect(headers.get('Clerk-Node-Port')).toBe('4000');
625+
expect(headers.get('Clerk-X-Port')).toBe('4000');
626+
expect(headers.get('Clerk-X-Host')).toBe('integration-forwarded-host');
627+
expect(headers.get('Clerk-X-Protocol')).toBe('https');
628+
expect(headers.get('Clerk-Auth-Status')).toBe('integration-status');
629+
expect(headers.get('Clerk-NPM-Config-User-Agent')).toBe('test-npm-agent');
630+
expect(headers.get('Clerk-Is-CI')).toBe('true'); // Should be 'true' when CI environment is detected
478631
});
479632
});

0 commit comments

Comments
 (0)