132 lines
4.4 KiB
JavaScript
132 lines
4.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { loadConfig } from '../src/config/env.js';
|
|
import { connectFirstAvailableMongo } from '../src/plugins/mongo.js';
|
|
|
|
function fakeClient(error = null) {
|
|
return {
|
|
closed: false,
|
|
async connect() {
|
|
if (error) throw error;
|
|
},
|
|
async close() {
|
|
this.closed = true;
|
|
},
|
|
};
|
|
}
|
|
|
|
test('Windows에서 개발용 MongoDB와 로컬 이미지 프로필을 자동 사용한다', () => {
|
|
const config = loadConfig({}, { platform: 'win32' });
|
|
|
|
assert.equal(config.nodeEnv, 'development');
|
|
assert.equal(config.mongoUri, 'mongodb://192.168.0.240:27017/our_recipe_atlas');
|
|
assert.equal(config.mongoFallbackUri, 'mongodb://172.16.0.7:27017/our_recipe_atlas');
|
|
assert.deepEqual(config.mongoCollections, {
|
|
allowedEmails: 'allowed_google_emails',
|
|
recipes: 'recipes_dev',
|
|
users: 'users_dev',
|
|
});
|
|
assert.match(config.imageRoot, /data\\images$/);
|
|
});
|
|
|
|
test('OS 프로필이 환경파일의 개발·운영 선택값보다 우선한다', () => {
|
|
const linuxConfig = loadConfig(
|
|
{
|
|
NODE_ENV: 'development',
|
|
MONGO_URI: 'mongodb://192.168.0.240:27017/our_recipe_atlas_dev',
|
|
IMAGE_ROOT: './data/images',
|
|
AUTH_JWT_SECRET: 'production-secret',
|
|
},
|
|
{ platform: 'linux' },
|
|
);
|
|
assert.equal(linuxConfig.nodeEnv, 'production');
|
|
assert.equal(linuxConfig.mongoUri, 'mongodb://192.168.0.240:27017/our_recipe_atlas');
|
|
assert.deepEqual(linuxConfig.mongoCollections, {
|
|
allowedEmails: 'allowed_google_emails',
|
|
recipes: 'recipes',
|
|
users: 'users',
|
|
});
|
|
assert.equal(linuxConfig.imageRoot, '/mnt/recipe-ssd/our_recipe_atlas/images');
|
|
|
|
const windowsConfig = loadConfig(
|
|
{
|
|
NODE_ENV: 'production',
|
|
MONGO_URI: 'mongodb://192.168.0.240:27017/our_recipe_atlas',
|
|
IMAGE_ROOT: '/mnt/recipe-ssd/our_recipe_atlas/images',
|
|
},
|
|
{ platform: 'win32' },
|
|
);
|
|
assert.equal(windowsConfig.nodeEnv, 'development');
|
|
assert.equal(windowsConfig.mongoUri, 'mongodb://192.168.0.240:27017/our_recipe_atlas');
|
|
assert.equal(windowsConfig.mongoCollections.recipes, 'recipes_dev');
|
|
assert.match(windowsConfig.imageRoot, /data\\images$/);
|
|
});
|
|
|
|
test('Linux 운영용 MongoDB와 절대 이미지 경로 설정을 허용한다', () => {
|
|
const config = loadConfig(
|
|
{ AUTH_JWT_SECRET: 'production-secret' },
|
|
{ platform: 'linux' },
|
|
);
|
|
|
|
assert.equal(config.nodeEnv, 'production');
|
|
assert.equal(config.mongoUri, 'mongodb://192.168.0.240:27017/our_recipe_atlas');
|
|
assert.equal(config.mongoFallbackUri, 'mongodb://172.16.0.7:27017/our_recipe_atlas');
|
|
assert.equal(config.imageRoot, '/mnt/recipe-ssd/our_recipe_atlas/images');
|
|
});
|
|
|
|
test('primary MongoDB 연결에 성공하면 fallback을 시도하지 않는다', async () => {
|
|
const createdUris = [];
|
|
const primary = fakeClient();
|
|
|
|
const result = await connectFirstAvailableMongo(['primary', 'fallback'], {
|
|
createClient(uri) {
|
|
createdUris.push(uri);
|
|
return primary;
|
|
},
|
|
});
|
|
|
|
assert.equal(result.client, primary);
|
|
assert.equal(result.connectionIndex, 0);
|
|
assert.deepEqual(createdUris, ['primary']);
|
|
});
|
|
|
|
test('primary MongoDB 연결 실패 시 정리한 뒤 fallback으로 연결한다', async () => {
|
|
const primaryError = new Error('primary unavailable');
|
|
const primary = fakeClient(primaryError);
|
|
const fallback = fakeClient();
|
|
const failures = [];
|
|
|
|
const result = await connectFirstAvailableMongo(['primary', 'fallback'], {
|
|
createClient(uri) {
|
|
return uri === 'primary' ? primary : fallback;
|
|
},
|
|
onFailure(index, error) {
|
|
failures.push({ index, error });
|
|
},
|
|
});
|
|
|
|
assert.equal(primary.closed, true);
|
|
assert.equal(fallback.closed, false);
|
|
assert.equal(result.client, fallback);
|
|
assert.equal(result.connectionIndex, 1);
|
|
assert.deepEqual(failures, [{ index: 0, error: primaryError }]);
|
|
});
|
|
|
|
test('모든 MongoDB 연결 실패 시 마지막 오류를 반환하고 클라이언트를 정리한다', async () => {
|
|
const primary = fakeClient(new Error('primary unavailable'));
|
|
const fallbackError = new Error('fallback unavailable');
|
|
const fallback = fakeClient(fallbackError);
|
|
|
|
await assert.rejects(
|
|
connectFirstAvailableMongo(['primary', 'fallback'], {
|
|
createClient(uri) {
|
|
return uri === 'primary' ? primary : fallback;
|
|
},
|
|
}),
|
|
fallbackError,
|
|
);
|
|
|
|
assert.equal(primary.closed, true);
|
|
assert.equal(fallback.closed, true);
|
|
});
|