File size: 4,435 Bytes
f0743f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// const OpenAI = require('openai');
const { ProxyAgent } = require('undici');
const { ErrorTypes, EModelEndpoint } = require('librechat-data-provider');
const { getUserKey, getUserKeyExpiry, getUserKeyValues } = require('~/server/services/UserService');
const initializeClient = require('./initialize');
// const { OpenAIClient } = require('~/app');

jest.mock('~/server/services/UserService', () => ({
  getUserKey: jest.fn(),
  getUserKeyExpiry: jest.fn(),
  getUserKeyValues: jest.fn(),
  checkUserKeyExpiry: jest.requireActual('~/server/services/UserService').checkUserKeyExpiry,
}));

// Config is now passed via req.config, not getAppConfig

const today = new Date();
const tenDaysFromToday = new Date(today.setDate(today.getDate() + 10));
const isoString = tenDaysFromToday.toISOString();

describe('initializeClient', () => {
  // Set up environment variables
  const originalEnvironment = process.env;
  const app = {
    locals: {},
  };

  beforeEach(() => {
    jest.resetModules(); // Clears the cache
    process.env = { ...originalEnvironment }; // Make a copy
  });

  afterAll(() => {
    process.env = originalEnvironment; // Restore original env vars
  });

  test('initializes OpenAI client with default API key and URL', async () => {
    process.env.AZURE_ASSISTANTS_API_KEY = 'default-api-key';
    process.env.AZURE_ASSISTANTS_BASE_URL = 'https://default.api.url';

    // Assuming 'isUserProvided' to return false for this test case
    jest.mock('~/server/utils', () => ({
      isUserProvided: jest.fn().mockReturnValueOnce(false),
    }));

    const req = {
      user: { id: 'user123' },
      app,
      config: { endpoints: { [EModelEndpoint.azureOpenAI]: {} } },
    };
    const res = {};

    const { openai, openAIApiKey } = await initializeClient({ req, res });
    expect(openai.apiKey).toBe('default-api-key');
    expect(openAIApiKey).toBe('default-api-key');
    expect(openai.baseURL).toBe('https://default.api.url');
  });

  test('initializes OpenAI client with user-provided API key and URL', async () => {
    process.env.AZURE_ASSISTANTS_API_KEY = 'user_provided';
    process.env.AZURE_ASSISTANTS_BASE_URL = 'user_provided';

    getUserKeyValues.mockResolvedValue({ apiKey: 'user-api-key', baseURL: 'https://user.api.url' });
    getUserKeyExpiry.mockResolvedValue(isoString);

    const req = {
      user: { id: 'user123' },
      app,
      config: { endpoints: { [EModelEndpoint.azureOpenAI]: {} } },
    };
    const res = {};

    const { openai, openAIApiKey } = await initializeClient({ req, res });
    expect(openAIApiKey).toBe('user-api-key');
    expect(openai.apiKey).toBe('user-api-key');
    expect(openai.baseURL).toBe('https://user.api.url');
  });

  test('throws error for invalid JSON in user-provided values', async () => {
    process.env.AZURE_ASSISTANTS_API_KEY = 'user_provided';
    getUserKey.mockResolvedValue('invalid-json');
    getUserKeyExpiry.mockResolvedValue(isoString);
    getUserKeyValues.mockImplementation(() => {
      let userValues = getUserKey();
      try {
        userValues = JSON.parse(userValues);
      } catch {
        throw new Error(
          JSON.stringify({
            type: ErrorTypes.INVALID_USER_KEY,
          }),
        );
      }
      return userValues;
    });

    const req = {
      user: { id: 'user123' },
      config: { endpoints: { [EModelEndpoint.azureOpenAI]: {} } },
    };
    const res = {};

    await expect(initializeClient({ req, res })).rejects.toThrow(/invalid_user_key/);
  });

  test('throws error if API key is not provided', async () => {
    delete process.env.AZURE_ASSISTANTS_API_KEY; // Simulate missing API key

    const req = {
      user: { id: 'user123' },
      app,
      config: { endpoints: { [EModelEndpoint.azureOpenAI]: {} } },
    };
    const res = {};

    await expect(initializeClient({ req, res })).rejects.toThrow(/Assistants API key not/);
  });

  test('initializes OpenAI client with proxy configuration', async () => {
    process.env.AZURE_ASSISTANTS_API_KEY = 'test-key';
    process.env.PROXY = 'http://proxy.server';

    const req = {
      user: { id: 'user123' },
      app,
      config: { endpoints: { [EModelEndpoint.azureOpenAI]: {} } },
    };
    const res = {};

    const { openai } = await initializeClient({ req, res });
    expect(openai.fetchOptions).toBeDefined();
    expect(openai.fetchOptions.dispatcher).toBeInstanceOf(ProxyAgent);
  });
});