Skip to content

Commit

Permalink
Merge branch 'development' into 6958-IX-grouped-thesaurus-value-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
konzz authored Jul 15, 2024
2 parents 7ac8016 + c9c6038 commit 3b2bc88
Show file tree
Hide file tree
Showing 96 changed files with 1,211 additions and 1,439 deletions.
14 changes: 7 additions & 7 deletions app/api/activitylog/specs/activitylogMiddleware.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { deleteFile, storage } from 'api/files';
import { tenants } from 'api/tenants';
import date from 'api/utils/date';
import { testingEnvironment } from 'api/utils/testingEnvironment';
import { errorLog } from 'api/log';
import { legacyLogger } from 'api/log';
// eslint-disable-next-line node/no-restricted-import
import fs from 'fs/promises';
import waitForExpect from 'wait-for-expect';
Expand Down Expand Up @@ -106,28 +106,28 @@ describe('activitylogMiddleware', () => {
});

it('should catch errors when saving log entry on db', async () => {
jest.spyOn(errorLog, 'error').mockImplementation(() => ({}));
jest.spyOn(legacyLogger, 'error').mockImplementation(() => ({}));
jest
.spyOn(activitylog, 'save')
.mockImplementation(async () => Promise.reject(new Error('activitylog save error')));

activitylogMiddleware(req, res, next);
await waitForExpect(() => {
expect(errorLog.error).toHaveBeenCalled();
expect(errorLog.error.mock.calls[0][0]).toMatch('activitylog save error');
expect(legacyLogger.error).toHaveBeenCalled();
expect(legacyLogger.error.mock.calls[0][0]).toMatch('activitylog save error');
});
});

it('should catch errors when saving log entry on filesystem', async () => {
jest.spyOn(errorLog, 'error').mockImplementation(() => ({}));
jest.spyOn(legacyLogger, 'error').mockImplementation(() => ({}));
jest
.spyOn(storage, 'storeFile')
.mockImplementation(async () => Promise.reject(new Error('storage save error')));

activitylogMiddleware(req, res, next);
await waitForExpect(() => {
expect(errorLog.error).toHaveBeenCalled();
expect(errorLog.error.mock.calls[0][0]).toMatch('storage save error');
expect(legacyLogger.error).toHaveBeenCalled();
expect(legacyLogger.error.mock.calls[0][0]).toMatch('storage save error');
});
});

Expand Down
1 change: 1 addition & 0 deletions app/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ export default (app, server) => {
require('./preserve/routes').PreserveRoutes(app);
require('./relationships.v2/routes/routes').default(app);
require('./stats/routes').default(app);
require('./testing_errors/routes').default(app);
};
14 changes: 9 additions & 5 deletions app/api/common.v2/database/specs/MongoDataSourceSync.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* eslint-disable max-statements */
import { StandardLogger } from 'api/log.v2/infrastructure/StandardLogger';
import { getIdMapper } from 'api/utils/fixturesFactory';
import { testingEnvironment } from 'api/utils/testingEnvironment';
import testingDB from 'api/utils/testing_db';
import { ObjectId } from 'mongodb';
import { getConnection } from '../getConnectionForCurrentTenant';
import { MongoClient, ObjectId } from 'mongodb';
import { MongoDataSource } from '../MongoDataSource';
import { DefaultTransactionManager } from '../data_source_defaults';
import { MongoTransactionManager } from '../MongoTransactionManager';
import { getClient, getConnection, getTenant } from '../getConnectionForCurrentTenant';

const id = getIdMapper();

Expand Down Expand Up @@ -37,6 +38,9 @@ const updateLogsBlankState = [
},
];

const createTransactionManager = (client?: MongoClient) =>
new MongoTransactionManager(client ?? getClient(), new StandardLogger(() => {}, getTenant()));

beforeEach(async () => {
await testingEnvironment.setUp({
collection: blankState,
Expand Down Expand Up @@ -662,7 +666,7 @@ describe('collection with automatic log to updatelogs', () => {
expectedResult,
expectedDBStateOnTransactionError = updateLogsBlankState,
}) => {
const transactionManager1 = DefaultTransactionManager();
const transactionManager1 = createTransactionManager();
const dataSource1 = new DataSource(getConnection(), transactionManager1);

try {
Expand All @@ -679,7 +683,7 @@ describe('collection with automatic log to updatelogs', () => {
);
}

const transactionManager2 = DefaultTransactionManager();
const transactionManager2 = createTransactionManager();
const dataSource2 = new DataSource(getConnection(), transactionManager2);

const result = await transactionManager2.run(async () => callback(dataSource2));
Expand Down
3 changes: 3 additions & 0 deletions app/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { version } from '../../package.json';

const {
ROOT_PATH,
JSON_LOGS,
UPLOADS_FOLDER,
CUSTOM_UPLOADS_FOLDER,
ACTIVITY_LOGS_FOLDER,
Expand All @@ -30,6 +31,8 @@ const onlyDBHOST = () => (DBHOST ? `mongodb://${DBHOST}/` : 'mongodb://127.0.0.1
export const config = {
VERSION: ENVIRONMENT ? version : `development-${version}`,

JSON_LOGS: JSON_LOGS || false,

ENVIRONMENT: ENVIRONMENT || 'development',

PORT: process.env.PORT || 3000,
Expand Down
21 changes: 0 additions & 21 deletions app/api/entities/entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import templates from 'api/templates/templates';
import { generateNames } from 'api/templates/utils';
import date from 'api/utils/date';
import { unique } from 'api/utils/filters';
import { objectIndex } from 'shared/data_utils/objectIndex';
import { AccessLevels } from 'shared/types/permissionSchema';
import { propertyTypes } from 'shared/propertyTypes';
import ID from 'shared/uniqueID';
Expand Down Expand Up @@ -534,26 +533,6 @@ export default {
return doc;
},

async saveMultiple(docs) {
const templateIds = Array.from(new Set(docs.map(d => d.template)));
const indexedTemplates = objectIndex(
await templates.get({ _id: { $in: templateIds } }),
t => t._id.toString(),
t => t
);

await docs.reduce(async (prev, _doc) => {
await prev;
const template = indexedTemplates[_doc.template];
const doc = this.sanitize(_doc, template);
await validateEntity(doc);
}, Promise.resolve());

const response = await model.saveMultiple(docs);
await search.indexEntities({ _id: { $in: response.map(d => d._id) } }, '+fullText');
return response;
},

async multipleUpdate(ids, values, params) {
const { diffMetadata = {}, ...pureValues } = values;

Expand Down
6 changes: 3 additions & 3 deletions app/api/entities/managerFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { WithId } from 'api/odm';
import { files as filesAPI, storage } from 'api/files';
import { processDocument } from 'api/files/processDocument';
import { search } from 'api/search';
import { errorLog } from 'api/log';
import { legacyLogger } from 'api/log';
import { prettifyError } from 'api/utils/handleError';
import { ClientEntitySchema } from 'app/istore';
import { FileType } from 'shared/types/fileType';
Expand Down Expand Up @@ -190,7 +190,7 @@ const saveFiles = async (
try {
await filesAPI.save(file, false);
} catch (e) {
errorLog.error(prettifyError(e));
legacyLogger.error(prettifyError(e));
saveResults.push(`Could not save file/s: ${file.originalname}`);
}
})
Expand All @@ -205,7 +205,7 @@ const saveFiles = async (
.filter(result => result.status === 'rejected')
.map(rejected => {
const { reason } = rejected as PromiseRejectedResult;
return errorLog.error(prettifyError(reason));
return legacyLogger.error(prettifyError(reason));
});

if (socketEmiter) {
Expand Down
97 changes: 1 addition & 96 deletions app/api/entities/specs/entities.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1127,101 +1127,6 @@ describe('entities', () => {
});
});

describe('saveMultiple()', () => {
it('should allow partial saveMultiple with correct full indexing', done => {
const partialDoc = { _id: batmanFinishesId, sharedId: 'shared', title: 'Updated title' };
const partialDoc2 = {
_id: syncPropertiesEntityId,
sharedId: 'shared',
title: 'Updated title 2',
};
entities
.saveMultiple([partialDoc, partialDoc2])
.then(response => Promise.all([response, entities.getById(batmanFinishesId)]))
.then(([response, savedEntity]) => {
const expectedQuery = {
_id: { $in: [batmanFinishesId, syncPropertiesEntityId] },
};

expect(response[0]._id.toString()).toBe(batmanFinishesId.toString());
expect(savedEntity.title).toBe('Updated title');
expect(savedEntity.metadata).toEqual(
expect.objectContaining({
property1: [{ value: 'value1' }],
friends: [{ icon: null, label: 'shared2title', type: 'entity', value: 'shared2' }],
})
);
expect(search.indexEntities).toHaveBeenCalledWith(expectedQuery, '+fullText');
done();
})
.catch(done.fail);
});

it('should sanitize the entities', async () => {
const sanitizationSpy = jest.spyOn(entities, 'sanitize');
const docsToSave = [
{
title: 'Batman begins',
template: templateId,
language: 'es',
metadata: {
multiselect: [{ value: 'country_one' }, { value: 'country_two' }],
friends: [{ value: 'id1' }, { value: 'id2' }],
},
},
{
title: 'Batman begins',
template: templateId,
language: 'en',
metadata: {
multiselect: [{ value: 'country_one' }, { value: 'country_two' }],
friends: [{ value: 'id1' }, { value: 'id2' }],
},
},
{
title: 'Batman Goes On',
template: entityGetTestTemplateId,
language: 'en',
metadata: {
some_property: [{ value: 'some value' }],
},
},
];
await entities.saveMultiple(docsToSave);
expect(sanitizationSpy.mock.calls).toMatchObject([
[
{
title: 'Batman begins',
language: 'es',
},
{
name: 'template_test',
},
],
[
{
title: 'Batman begins',
language: 'en',
},
{
name: 'template_test',
},
],
[
{
title: 'Batman Goes On',
language: 'en',
},
{
name: 'entityGetTestTemplate',
},
],
]);

sanitizationSpy.mockRestore();
});
});

describe('updateMetadataProperties', () => {
let currentTemplate;
beforeEach(() => {
Expand Down Expand Up @@ -1508,7 +1413,7 @@ describe('entities', () => {
});

it('should duplicate all the entities from the default language to the new one', async () => {
await entities.saveMultiple([{ _id: docId1, file: {} }]);
await entitiesModel.save({ _id: docId1, file: {} });

await entities.addLanguage('ab', 2);
const newEntities = await entities.get({ language: 'ab' }, '+permissions');
Expand Down
10 changes: 0 additions & 10 deletions app/api/entities/specs/entitySavingManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { saveEntity } from 'api/entities/entitySavingManager';
import * as os from 'os';
import { attachmentsPath, fileExistsOnPath, files as filesAPI, uploadsPath } from 'api/files';
import * as processDocumentApi from 'api/files/processDocument';
import { errorLog } from 'api/log';
import { search } from 'api/search';
import db from 'api/utils/testing_db';
import { advancedSort } from 'app/utils/advancedSort';
Expand All @@ -13,7 +12,6 @@ import { ObjectId } from 'mongodb';
import path from 'path';
import { EntityWithFilesSchema } from 'shared/types/entityType';
import waitForExpect from 'wait-for-expect';
import { Logger } from 'winston';
import entities from '../entities';
import {
anotherTextFile,
Expand Down Expand Up @@ -209,11 +207,8 @@ describe('entitySavingManager', () => {

describe('file save error', () => {
let entity: EntityWithFilesSchema;
let originalSilent: boolean | undefined;

beforeAll(() => {
originalSilent = errorLog.transports[1].silent;
errorLog.transports[1].silent = true;
entity = {
_id: entity1Id,
sharedId: 'shared1',
Expand All @@ -223,10 +218,6 @@ describe('entitySavingManager', () => {
};
});

afterAll(() => {
errorLog.transports[1].silent = originalSilent;
});

it('should continue saving if a file fails to save', async () => {
const { entity: savedEntity } = await saveEntity(entity, { ...reqData });
expect(savedEntity.attachments).toEqual([textFile]);
Expand Down Expand Up @@ -603,7 +594,6 @@ describe('entitySavingManager', () => {
});

it('should return an error if an existing main document cannot be saved', async () => {
jest.spyOn(errorLog, 'error').mockImplementationOnce(() => ({}) as Logger);
jest.spyOn(filesAPI, 'save').mockRejectedValueOnce({ error: { name: 'failed' } });

const { errors } = await saveEntity(
Expand Down
7 changes: 3 additions & 4 deletions app/api/entities/specs/routes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import db from 'api/utils/testing_db';

import * as entitySavingManager from 'api/entities/entitySavingManager';
import routes from 'api/entities/routes';
import { errorLog } from 'api/log';
import { legacyLogger } from 'api/log';
import templates from 'api/templates';
import thesauri from 'api/thesauri';
import { UserInContextMockFactory } from 'api/utils/testingUserInContext';
import path from 'path';
import { AccessLevels, PermissionType } from 'shared/types/permissionSchema';
import { UserRole } from 'shared/types/userSchema';
import { ObjectId } from 'mongodb';
import { Logger } from 'winston';
import fixtures, { permissions } from './fixtures';

jest.mock(
Expand Down Expand Up @@ -232,7 +231,7 @@ describe('entities routes', () => {
jest
.spyOn(thesauri, 'templateToThesauri')
.mockImplementation(async () => Promise.resolve({}));
jest.spyOn(errorLog, 'debug').mockImplementation(() => ({}) as Logger);
jest.spyOn(legacyLogger, 'error').mockImplementation(() => ({}));

await request(app)
.post('/api/entities')
Expand All @@ -242,7 +241,7 @@ describe('entities routes', () => {
.attach('attachments[0]', path.join(__dirname, 'Hello, World.pdf'), 'Nombre en español 3')
.attach('attachments[1]', path.join(__dirname, 'Hello, World.pdf'), 'Nombre en español 4');

expect(errorLog.debug).toHaveBeenCalledWith(expect.stringContaining('Deprecation'));
expect(legacyLogger.error).toHaveBeenCalledWith(expect.stringContaining('Deprecation'));
});
});
});
4 changes: 2 additions & 2 deletions app/api/files/PDF.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// eslint-disable-next-line node/no-restricted-import
import { createReadStream } from 'fs';
import * as os from 'os';
import { errorLog } from 'api/log';
import { legacyLogger } from 'api/log';
import { createError } from 'api/utils';
import { spawn } from 'child-process-promise';
import EventEmitter from 'events';
Expand Down Expand Up @@ -74,7 +74,7 @@ class PDF extends EventEmitter {
await storage.storeFile(response, createReadStream(thumbnailPath), 'thumbnail');
} catch (err) {
response = err;
errorLog.error(err.stderr);
legacyLogger.error(err.stderr);
}

return Promise.resolve(response);
Expand Down
Loading

0 comments on commit 3b2bc88

Please sign in to comment.