-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup-token.test.ts
More file actions
102 lines (94 loc) · 3 KB
/
Copy pathsetup-token.test.ts
File metadata and controls
102 lines (94 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { CredentialsStore } from '@deepcode/core';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { Readable, Writable } from 'node:stream';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { runSetupToken } from './setup-token.js';
function sink(): { stream: Writable; text: () => string } {
let buf = '';
const stream = new Writable({
write(c, _e, cb) {
buf += c.toString();
cb();
},
});
return { stream, text: () => buf };
}
/** A non-TTY readable carrying `data` (mimics a pipe). */
function pipe(data: string): Readable & { isTTY?: boolean } {
const r = Readable.from([Buffer.from(data)]) as Readable & { isTTY?: boolean };
r.isTTY = false;
return r;
}
describe('runSetupToken', () => {
let home: string;
beforeEach(async () => {
home = await mkdtemp(join(tmpdir(), 'dc-tok-'));
});
afterEach(async () => {
await rm(home, { recursive: true, force: true });
});
it('stores a token passed as an argument', async () => {
const out = sink();
const code = await runSetupToken({
token: 'tok-abc123',
home,
output: out.stream,
env: {},
forceFile: true,
});
expect(code).toBe(0);
expect(out.text()).toMatch(/Stored DeepSeek auth token/);
expect((await new CredentialsStore({ home, forceFile: true }).load()).authToken).toBe(
'tok-abc123',
);
});
it('reads the token from $DEEPSEEK_AUTH_TOKEN', async () => {
await runSetupToken({
home,
output: sink().stream,
env: { DEEPSEEK_AUTH_TOKEN: 'env-tok' },
forceFile: true,
});
expect((await new CredentialsStore({ home, forceFile: true }).load()).authToken).toBe(
'env-tok',
);
});
it('reads a piped token from stdin (non-TTY)', async () => {
await runSetupToken({
home,
output: sink().stream,
env: {},
stdin: pipe('piped-tok\n'),
forceFile: true,
});
expect((await new CredentialsStore({ home, forceFile: true }).load()).authToken).toBe(
'piped-tok',
);
});
it('preserves an existing apiKey/baseURL when adding the token', async () => {
await new CredentialsStore({ home, forceFile: true }).save({
apiKey: 'sk-keep',
baseURL: 'https://x/v1',
});
await runSetupToken({ token: 't', home, output: sink().stream, env: {}, forceFile: true });
const creds = await new CredentialsStore({ home, forceFile: true }).load();
expect(creds.apiKey).toBe('sk-keep');
expect(creds.authToken).toBe('t');
expect(creds.baseURL).toBe('https://x/v1');
});
it('errors with usage when no token is available', async () => {
const err = sink();
const ttyStdin = Object.assign(Readable.from([]), { isTTY: true });
const code = await runSetupToken({
home,
errOutput: err.stream,
env: {},
stdin: ttyStdin,
forceFile: true,
});
expect(code).toBe(2);
expect(err.text()).toMatch(/Usage: deepcode setup-token/);
});
});