Skip to content

Commit

Permalink
Merge branch 'development' into 1702-debug-logging
Browse files Browse the repository at this point in the history
  • Loading branch information
txau authored Jun 29, 2018
2 parents 27da5fc + 6db1824 commit 10b4951
Show file tree
Hide file tree
Showing 33 changed files with 1,198 additions and 112 deletions.
7 changes: 6 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"presets": ["env", "react"],
"presets": [["env", {
"targets": {
"node": "current"
}
}], "react"],
"retainLines": "true",
"env": {
"production": {
Expand All @@ -11,6 +15,7 @@
}
},
"plugins": [
"transform-object-rest-spread",
"transform-es2015-typeof-symbol",
"transform-class-properties",
"add-module-exports",
Expand Down
11 changes: 6 additions & 5 deletions app/api/search/specs/analyzers.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import elastic from '../elastic';
import { catchErrors } from 'api/utils/jasmineHelpers';
import { index as elasticIndex } from 'api/config/elasticIndexes';
import instanceElasticTesting from 'api/utils/elastic_testing';
import {index as elasticIndex} from 'api/config/elasticIndexes';
import {catchErrors} from 'api/utils/jasmineHelpers';

import elastic from '../elastic';

describe('custom language analyzers', () => {
const elasticTesting = instanceElasticTesting('analyzers_index_test');
Expand All @@ -12,13 +13,13 @@ describe('custom language analyzers', () => {

describe('persian', () => {
it('should index persian without errors', (done) => {
let persianText = `براي مشارکت فعال در کالس آماده باشيد. برای رسیدن به این هدف، بايد پیش از کالس به فايلهاي صوتي گوش کنيد،
const persianText = `براي مشارکت فعال در کالس آماده باشيد. برای رسیدن به این هدف، بايد پیش از کالس به فايلهاي صوتي گوش کنيد،
ويديوها را ببينيد و تمرينهاي آنها را انجام دهيد. به صداهاي جديد گوش کنيد و حروف جديد را بنويسيد. هر چهقدر الزم است
اين کار را تکرار کنید، تا وقتي که شناختن و توليد اين صداها و حروف برايتان راحت و آسان شود. تمرينهاي در خانه را پيش
از کالس انجام دهيد تا براي خواندن و نوشتن در کالس آماده باشيد. وقت کالس بايد صرف تمرين شود، نه شنيدن سخنراني
استادتان.`;

elastic.index({index: elasticIndex, type: 'fullText', body: {fullText_persian: persianText}, id: '123_whatever', parent: 123})
elastic.index({ index: elasticIndex, type: 'fullText', body: { fullText_persian: persianText }, id: '123_whatever', parent: 123 })
.then(() => done())
.catch(done.fail);
});
Expand Down
32 changes: 29 additions & 3 deletions app/api/upload/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ import errorLog from 'api/log/errorLog';
import fs from 'fs';
import path from 'path';
import multer from 'multer';

import ID from 'shared/uniqueID';
import languages from 'shared/languages';
import entities from 'api/entities';
import fs from 'fs';
import languages from 'shared/languages';
import logger from 'shared/logger';
import relationships from 'api/relationships';

import { uploadDocumentsPath } from '../config/paths';
import PDF from './PDF';
import needsAuthorization from '../auth/authMiddleware';
import { uploadDocumentsPath } from '../config/paths';
import uploads from './uploads';

const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, path.normalize(`${uploadDocumentsPath}/`));
},
filename(req, file, cb) {
cb(null, `${Date.now() + ID()}.pdf`);
cb(null, Date.now() + ID() + path.extname(file.originalname));
}
});

Expand Down Expand Up @@ -95,6 +100,27 @@ export default (app) => {

app.post('/api/upload', needsAuthorization(['admin', 'editor']), upload.any(), (req, res) => uploadProcess(req, res));

app.post('/api/customisation/upload', needsAuthorization(['admin', 'editor']), upload.any(), (req, res) => {
uploads.save(req.files[0])
.then((saved) => {
res.json(saved);
});
});

app.get('/api/customisation/upload', needsAuthorization(['admin', 'editor']), (req, res) => {
uploads.get()
.then((result) => {
res.json(result);
});
});

app.delete('/api/customisation/upload', needsAuthorization(['admin', 'editor']), (req, res) => {
uploads.delete(req.query._id)
.then((result) => {
res.json(result);
});
});

app.post('/api/reupload', needsAuthorization(['admin', 'editor']), upload.any(), (req, res) => entities.getById(req.body.document)
.then(doc => Promise.all([doc, relationships.deleteTextReferences(doc.sharedId, doc.language)]))
.then(([doc]) => entities.saveMultiple([{ _id: doc._id, toc: [] }]))
Expand Down
18 changes: 18 additions & 0 deletions app/api/upload/specs/__snapshots__/routes.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`upload routes GET/customisation/upload should return all uploads 1`] = `
Array [
"upload1",
"upload2",
]
`;

exports[`upload routes POST/customisation/upload should save the upload and return it 1`] = `
Object {
"__v": 0,
"filename": "f2082bf51b6ef839690485d7153e847a.pdf",
"mimetype": "application/octet-stream",
"originalname": "gadgets-01.pdf",
"size": 171411271,
}
`;
12 changes: 9 additions & 3 deletions app/api/upload/specs/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import db from 'api/utils/testing_db';

const entityId = db.id();
const uploadId = db.id();

export default {
entities: [
{_id: entityId, sharedId: 'id', language: 'es', title: 'Gadgets 01 ES', toc: [{_id: db.id(), label: 'existingToc'}]},
{_id: db.id(), sharedId: 'id', language: 'en', title: 'Gadgets 01 EN'}
{ _id: entityId, sharedId: 'id', language: 'es', title: 'Gadgets 01 ES', toc: [{ _id: db.id(), label: 'existingToc' }] },
{ _id: db.id(), sharedId: 'id', language: 'en', title: 'Gadgets 01 EN' }
],
uploads: [
{ _id: uploadId, originalname: 'upload1' },
{ _id: db.id(), originalname: 'upload2' },
]
};

export {
entityId
entityId,
uploadId
};
26 changes: 26 additions & 0 deletions app/api/upload/specs/routes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import fixtures, { entityId } from './fixtures.js';
import instrumentRoutes from '../../utils/instrumentRoutes';
import uploadRoutes from '../routes.js';
import errorLog from '../../log/errorLog';
import uploads from '../uploads.js';

describe('upload routes', () => {
let routes;
Expand Down Expand Up @@ -179,4 +180,29 @@ describe('upload routes', () => {
.catch(done.fail);
});
});

describe('POST/customisation/upload', () => {
it('should save the upload and return it', async () => {
const result = await routes.post('/api/customisation/upload', req);
delete result._id;
delete result.creationDate;
expect(result).toMatchSnapshot();
});
});

describe('GET/customisation/upload', () => {
it('should return all uploads', async () => {
const result = await routes.get('/api/customisation/upload', {});
expect(result.map(r => r.originalname)).toMatchSnapshot();
});
});

describe('DELETE/customisation/upload', () => {
it('should delete upload and return the response', async () => {
spyOn(uploads, 'delete').and.returnValue(Promise.resolve('upload_deleted'));
const result = await routes.delete('/api/customisation/upload', { query: { _id: 'upload_id' } });
expect(result).toBe('upload_deleted');
expect(uploads.delete).toHaveBeenCalledWith('upload_id');
});
});
});
62 changes: 62 additions & 0 deletions app/api/upload/specs/uploads.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* eslint-disable max-nested-callbacks */
import { catchErrors } from 'api/utils/jasmineHelpers';
import db from 'api/utils/testing_db';
import fs from 'fs';
import path from 'path';

import uploads from '../uploads';
import uploadsModel from '../uploadsModel';
import { uploadDocumentsPath } from '../../config/paths';

describe('uploads', () => {
let file;
const uploadId = db.id();

beforeEach((done) => {
file = {
fieldname: 'file',
originalname: 'gadgets-01.pdf',
encoding: '7bit',
mimetype: 'application/octet-stream',
destination: `${__dirname}/uploads/`,
filename: 'f2082bf51b6ef839690485d7153e847a.pdf',
path: `${__dirname}/uploads/f2082bf51b6ef839690485d7153e847a.pdf`,
size: 171411271
};

db.clearAllAndLoad({ uploads: [{ _id: uploadId, filename: 'upload.filename' }] }).then(done).catch(catchErrors(done));
});

afterAll((done) => {
db.disconnect().then(done);
});

describe('save', () => {
it('should save file passed', async () => {
let saved = await uploads.save(file);
saved = await uploadsModel.getById(saved._id);

expect(saved.creationDate).toBeDefined();

expect(saved).toMatchObject({
originalname: 'gadgets-01.pdf',
mimetype: 'application/octet-stream',
filename: 'f2082bf51b6ef839690485d7153e847a.pdf',
size: 171411271
});
});
});

describe('delete', () => {
fit('should delete the file', async () => {
fs.writeFileSync(path.join(uploadDocumentsPath, 'upload.filename'));

expect(fs.existsSync(path.join(uploadDocumentsPath, 'upload.filename'))).toBe(true);

await uploads.delete(uploadId);

expect(fs.existsSync(path.join(uploadDocumentsPath, 'upload.filename'))).toBe(false);
});
});
});

29 changes: 29 additions & 0 deletions app/api/upload/uploads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import fs from 'fs';
import path from 'path';

import { uploadDocumentsPath } from '../config/paths';
import model from './uploadsModel';

const deleteFile = filename => new Promise((resolve, reject) => {
fs.unlink(path.join(uploadDocumentsPath, filename), (err) => {
if (err) {
reject(err);
}
resolve();
});
});

export default {
save: model.save.bind(model),

get: model.get.bind(model),

async delete(_id) {
const upload = await model.getById(_id);

await model.delete(_id);
await deleteFile(upload.filename);

return upload;
}
};
17 changes: 17 additions & 0 deletions app/api/upload/uploadsModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose from 'mongoose';
import date from 'api/utils/date.js';

import instanceModel from 'api/odm';

const uploadSchema = new mongoose.Schema({
originalname: String,
filename: String,
mimetype: String,
size: Number,
creationDate: { type: Number, default: date.currentUTC },
}, { emitIndexErrors: true });

const schema = mongoose.model('uploads', uploadSchema);
const Model = instanceModel(schema);

export default Model;
16 changes: 10 additions & 6 deletions app/react/App/GoogleAnalytics.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {isClient} from 'app/utils';
import React, { Component } from 'react';

import { isClient } from 'app/utils';

export function trackPage() {
if (isClient && window.ga) {
Expand All @@ -10,7 +11,6 @@ export function trackPage() {
}

export class GoogleAnalytics extends Component {

constructor(props) {
super(props);
if (!props.analyticsTrackingId || !isClient) {
Expand All @@ -27,15 +27,19 @@ export class GoogleAnalytics extends Component {
if (!this.props.analyticsTrackingId) {
return false;
}
return <script async src='https://www.google-analytics.com/analytics.js'></script>;
return <script async src="https://www.google-analytics.com/analytics.js" />;
}
}

GoogleAnalytics.defaultProps = {
analyticsTrackingId: ''
};

GoogleAnalytics.propTypes = {
analyticsTrackingId: PropTypes.string
};

export function mapStateToProps({settings}) {
export function mapStateToProps({ settings }) {
return {
analyticsTrackingId: settings.collection.get('analyticsTrackingId')
};
Expand Down
Loading

0 comments on commit 10b4951

Please sign in to comment.