Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
daneryl committed Nov 22, 2018
2 parents ea2d13b + a183789 commit f0a8f37
Show file tree
Hide file tree
Showing 66 changed files with 8,411 additions and 1,165 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Intallation guide
# Dependencies

- **NodeJs 8.11.x** For ease of update, use nvm: https://github.com/creationix/nvm
- **ElasticSearch 5.5.x** https://www.elastic.co/guide/en/elasticsearch/reference/5.5/install-elasticsearch.html (Make sure to have 5.5, some sections of the instructions use 5.x which would install a different version). Please note that ElasticSearch requires java.
- **ElasticSearch 5.6.x** https://www.elastic.co/guide/en/elasticsearch/reference/5.5/install-elasticsearch.html (Make sure to have 5.5, some sections of the instructions use 5.x which would install a different version). Please note that ElasticSearch requires java.
- **MongoDB 3.4.x** https://docs.mongodb.com/v3.4/installation/ (there are known issues with 3.6, please ensure 3.4)
- **Yarn** https://yarnpkg.com/en/docs/install
- **pdftotext (Poppler)** tested to work on version 0.26 but its recommended to use the latest available for your platform https://poppler.freedesktop.org/
Expand Down
2 changes: 1 addition & 1 deletion app/api/auth/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default (app) => {
app.use(cookieParser());

app.use(session({
secret: uniqueID(),
secret: app.get('env') === 'production' ? uniqueID() : 'harvey&lola',
store: new MongoStore({
mongooseConnection: mongoose.connection
}),
Expand Down
39 changes: 39 additions & 0 deletions app/api/entities/entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,5 +448,44 @@ export default {
});
},

async addLanguage(language) {
const [lanuageTranslationAlreadyExists] = await this.get({ locale: language }, null, { limit: 1 });
if (lanuageTranslationAlreadyExists) {
return Promise.resolve();
}

const { languages } = await settings.get();

const defaultLanguage = languages.find(l => l.default).key;
const duplicate = (offset, totalRows) => {
const limit = 200;
if (offset >= totalRows) {
return Promise.resolve();
}

return this.get({ language: defaultLanguage }, null, { skip: offset, limit })
.then((entities) => {
const newLanguageEntities = entities.map((_entity) => {
const entity = Object.assign({}, _entity);
delete entity._id;
delete entity.__v;
entity.language = language;
return entity;
});

return this.saveMultiple(newLanguageEntities);
})
.then(() => duplicate(offset + limit, totalRows));
};

return this.count({ language: defaultLanguage })
.then(totalRows => duplicate(0, totalRows));
},

async removeLanguage(locale) {
return model.delete({ locale })
.then(() => search.deleteLanguage(locale));
},

count: model.count
};
6 changes: 3 additions & 3 deletions app/api/entities/entitiesModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ const entitySchema = new mongoose.Schema({
entitySchema.index({ title: 'text' }, { language_override: 'mongoLanguage' });

const schema = mongoose.model('entities', entitySchema);
schema.collection.dropIndex('title_text', () => { schema.ensureIndexes(); });
const Model = instanceModel(schema);

const { save } = Model;
const unsuportedLanguages = ['ar', 'sr', 'ka'];
const suportedLanguages = ['da', 'nl', 'en', 'fi', 'fr', 'de', 'hu', 'it', 'nb', 'pt', 'ro', 'ru', 'es', 'sv', 'tr'];

const setMongoLanguage = (doc) => {
if (!doc.language) {
return doc;
}

let mongoLanguage = doc.language;
if (unsuportedLanguages.includes(doc.language)) {
if (!suportedLanguages.includes(mongoLanguage)) {
mongoLanguage = 'none';
}

Expand Down
12 changes: 12 additions & 0 deletions app/api/entities/specs/entities.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,16 @@ describe('entities', () => {
.catch(catchErrors(done));
});
});

describe('addLanguage()', () => {
it('should duplicate all the entities from the default language to the new one', (done) => {
entities.addLanguage('ab')
.then(() => entities.get({ language: 'ab' }))
.then((newEntities) => {
expect(newEntities.length).toBe(7);
done();
})
.catch(catchErrors(done));
});
});
});
2 changes: 1 addition & 1 deletion app/api/entities/specs/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default {
{ _id: db.id(), template: templateWithOnlyMultiselect, sharedId: 'otherTemplateWithMultiselect', type: 'entity', language: 'es', metadata: { multiselect: ['value1', 'multiselect'] }, file: { filename: '123.pdf' } }
],
settings: [
{ _id: db.id(), languages: [{ key: 'es' }, { key: 'pt' }, { key: 'en' }] }
{ _id: db.id(), languages: [{ key: 'es', default: true }, { key: 'pt' }, { key: 'en' }] }
],
templates: [
{ _id: templateId,
Expand Down
80 changes: 64 additions & 16 deletions app/api/i18n/routes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Joi from 'joi';

import { validateRequest } from 'api/utils';
import settings from 'api/settings';
import entities from 'api/entities';

import needsAuthorization from '../auth/authMiddleware';
import translations from './translations';
Expand All @@ -17,7 +19,8 @@ export default (app) => {

needsAuthorization(),

validateRequest(Joi.object().keys({
validateRequest(Joi.object()
.keys({
_id: Joi.string(),
__v: Joi.number(),
locale: Joi.string().required(),
Expand All @@ -40,23 +43,68 @@ export default (app) => {
res.json(response);
})
.catch(next);
});
}
);

// app.post(
// '/api/translations/addentry',
app.post(
'/api/translations/setasdeafult',
needsAuthorization(),
validateRequest(Joi.object().keys({
key: Joi.string(),
}).required()),

// needsAuthorization(),
(req, res, next) => {
settings.setDefaultLanguage(req.body.key)
.then((response) => {
req.io.sockets.emit('updateSettings', response);
res.json(response);
})
.catch(next);
}
);

// validateRequest(Joi.object().keys({
// context: Joi.string().required(),
// key: Joi.string().required(),
// value: Joi.string().required(),
// }).required()),
app.post(
'/api/translations/languages',
needsAuthorization(),
validateRequest(Joi.object().keys({
key: Joi.string(),
label: Joi.string(),
}).required()),

(req, res, next) => {
Promise.all([
settings.addLanguage(req.body),
translations.addLanguage(req.body.key),
entities.addLanguage(req.body.key),
])
.then(([newSettings, newTranslations]) => {
req.io.sockets.emit('updateSettings', newSettings);
req.io.sockets.emit('translationsChange', newTranslations);
res.json(newSettings);
})
.catch(next);
}
);

app.delete(
'/api/translations/languages',
needsAuthorization(),
validateRequest(Joi.object().keys({
key: Joi.string(),
}).required()),

// (req, res, next) => {
// translations.addEntry(req.body.context, req.body.key, req.body.value)
// .then(response => res.json(response))
// .catch(next);
// }
// );
(req, res, next) => {
Promise.all([
settings.deleteLanguage(req.query.key),
translations.removeLanguage(req.query.key),
entities.removeLanguage(req.query.key),
])
.then(([newSettings, newTranslations]) => {
req.io.sockets.emit('updateSettings', newSettings);
req.io.sockets.emit('translationsChange', newTranslations);
res.json(newSettings);
})
.catch(next);
}
);
};
17 changes: 17 additions & 0 deletions app/api/i18n/specs/__snapshots__/routes.spec.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`i18n translations routes POST /api/translations/setasdeafult should have a validation schema 1`] = `
Object {
"children": Object {
"key": Object {
"invalids": Array [
"",
],
"type": "string",
},
},
"flags": Object {
"presence": "required",
},
"type": "object",
}
`;

exports[`i18n translations routes POST should have a validation schema 1`] = `
Object {
"children": Object {
Expand Down
22 changes: 14 additions & 8 deletions app/api/i18n/specs/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import db from 'api/utils/testing_db';

const entityTemplateId = db.id();
const documentTemplateId = db.id();
const englishTranslation = db.id();
Expand All @@ -9,30 +10,35 @@ export default {
locale: 'en',
contexts: [
{
_id: db.id(),
id: 'System',
label: 'System',
values: [
{key: 'Password', value: 'Password'},
{key: 'Account', value: 'Account'},
{key: 'Email', value: 'E-Mail'},
{key: 'Age', value: 'Age'}
{ key: 'Password', value: 'Password' },
{ key: 'Account', value: 'Account' },
{ key: 'Email', value: 'E-Mail' },
{ key: 'Age', value: 'Age' }
]
},
{
_id: db.id(),
id: 'Filters',
label: 'Filters'
},
{
_id: db.id(),
id: 'Menu',
label: 'Menu'
},
{
_id: db.id(),
id: entityTemplateId.toString(),
label: 'Judge',
values: [],
type: 'Entity'
},
{
_id: db.id(),
id: documentTemplateId.toString(),
label: 'Court order',
values: [],
Expand All @@ -49,10 +55,10 @@ export default {
id: 'System',
label: 'System',
values: [
{key: 'Password', value: 'Contraseña'},
{key: 'Account', value: 'Cuenta'},
{key: 'Email', value: 'Correo electronico'},
{key: 'Age', value: 'Edad'}
{ key: 'Password', value: 'Contraseña' },
{ key: 'Account', value: 'Cuenta' },
{ key: 'Email', value: 'Correo electronico' },
{ key: 'Age', value: 'Edad' }
]
}
]
Expand Down
31 changes: 19 additions & 12 deletions app/api/i18n/specs/routes.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { catchErrors } from 'api/utils/jasmineHelpers';
import settings from 'api/settings';
import i18nRoutes from 'api/i18n/routes.js';
import instrumentRoutes from 'api/utils/instrumentRoutes';
import translations from 'api/i18n/translations';
Expand Down Expand Up @@ -43,16 +44,22 @@ describe('i18n translations routes', () => {
});
});

// describe('POST addentry', () => {
// it('should add entry to a translation context', (done) => {
// spyOn(translations, 'addEntry').and.returnValue(mockRequest);
// routes.post('/api/translations/addentry', { body: { context: 'System', key: 'Search', value: 'Buscar' } })
// .then((response) => {
// expect(translations.addEntry).toHaveBeenCalledWith('System', 'Search', 'Buscar');
// expect(response).toEqual({ translations: 'response' });
// done();
// })
// .catch(catchErrors(done));
// });
// });
describe('POST /api/translations/setasdeafult', () => {
it('should have a validation schema', () => {
expect(routes.post.validation('/api/translations/setasdeafult')).toMatchSnapshot();
});

it('should update the setting', (done) => {
spyOn(settings, 'setDefaultLanguage').and.returnValue(Promise.resolve({ site_name: 'Uwazi' }));
const emit = jasmine.createSpy('emit');
routes.post('/api/translations/setasdeafult', { body: { key: 'fr' }, io: { sockets: { emit } } })
.then((response) => {
expect(settings.setDefaultLanguage).toHaveBeenCalledWith('fr');
expect(response).toEqual({ site_name: 'Uwazi' });
expect(emit).toHaveBeenCalledWith('updateSettings', { site_name: 'Uwazi' });
done();
})
.catch(catchErrors(done));
});
});
});
42 changes: 42 additions & 0 deletions app/api/i18n/specs/translations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,46 @@ describe('translations', () => {
.catch(catchErrors(done));
});
});

describe('addLanguage', () => {
it('should clone translations of default language and change language to the one added', async () => {
await translations.addLanguage('fr');
const allTranslations = await translations.get();

const frTranslation = allTranslations.find(t => t.locale === 'fr');
const defaultTranslation = allTranslations.find(t => t.locale === 'en');

expect(frTranslation.contexts[0]._id.toString()).not.toBe(defaultTranslation.contexts[0]._id.toString());
expect(frTranslation.contexts[1]._id.toString()).not.toBe(defaultTranslation.contexts[1]._id.toString());
expect(frTranslation.contexts[2]._id.toString()).not.toBe(defaultTranslation.contexts[2]._id.toString());
expect(frTranslation.contexts[3]._id.toString()).not.toBe(defaultTranslation.contexts[3]._id.toString());
expect(frTranslation.contexts[4]._id.toString()).not.toBe(defaultTranslation.contexts[4]._id.toString());

expect(frTranslation.contexts[0].values).toEqual(defaultTranslation.contexts[0].values);
expect(frTranslation.contexts[1].values).toEqual(defaultTranslation.contexts[1].values);
});

describe('when translation already exists', () => {
it('should not clone it again', async () => {
await translations.addLanguage('fr');
await translations.addLanguage('fr');
const allTranslations = await translations.get();

const frTranslations = allTranslations.filter(t => t.locale === 'fr');

expect(frTranslations.length).toBe(1);
});
});
});

describe('removeLanguage', () => {
it('should remove translation for the language passed', async () => {
await translations.removeLanguage('es');
await translations.removeLanguage('other');
const allTranslations = await translations.get();

expect(allTranslations.length).toBe(1);
expect(allTranslations[0].locale).toBe('en');
});
});
});
Loading

0 comments on commit f0a8f37

Please sign in to comment.