From 18306f5d982b65677f49bdfd881b294ce9cf7846 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Wed, 1 Aug 2018 11:58:01 -0700 Subject: [PATCH 1/3] updated build scripts --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3e29cd24..dac711c3 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,9 @@ "fix": "eslint . --fix", "lint": "eslint .", "precommit": "eslint .", - "start": "npm run server", - "start:dev": "builder concurrent transpile:dev bundle:dev server:dev", - "server": "node server.js", - "server:dev": "nodemon server.js", + "prestart": "builder run bundle", + "start": "node server.js", + "start:build": "builder run start", "test": "mocha --recursive", "test:no-lbc": "npm test -- --grep @usesLbc --invert", "transpile": "builder concurrent transpile:server transpile:client transpile:client_custom", From d2eaaae7590100dc4d9148e11bbf6a843bf2914b Mon Sep 17 00:00:00 2001 From: bill bittner Date: Wed, 1 Aug 2018 17:31:20 -0700 Subject: [PATCH 2/3] removed duplicate lbryUri parser module --- client/src/sagas/show_uri.js | 2 +- client/src/utils/lbryUri.js | 85 ------------------- server/controllers/api/oEmbed/index.js | 2 +- .../controllers/assets/serveByClaim/index.js | 2 +- .../assets/serveByIdentifierAndClaim/index.js | 2 +- .../controllers/utils => utils}/lbryUri.js | 16 ++-- 6 files changed, 9 insertions(+), 100 deletions(-) delete mode 100644 client/src/utils/lbryUri.js rename {server/controllers/utils => utils}/lbryUri.js (83%) diff --git a/client/src/sagas/show_uri.js b/client/src/sagas/show_uri.js index 52e21af7..00432f67 100644 --- a/client/src/sagas/show_uri.js +++ b/client/src/sagas/show_uri.js @@ -3,7 +3,7 @@ import * as actions from '../constants/show_action_types'; import { onRequestError, onNewChannelRequest, onNewAssetRequest } from '../actions/show'; import { newAssetRequest } from '../sagas/show_asset'; import { newChannelRequest } from '../sagas/show_channel'; -import lbryUri from '../utils/lbryUri'; +import lbryUri from '../../../utils/lbryUri'; function * parseAndUpdateIdentifierAndClaim (modifier, claim) { // this is a request for an asset diff --git a/client/src/utils/lbryUri.js b/client/src/utils/lbryUri.js deleted file mode 100644 index a197e1e0..00000000 --- a/client/src/utils/lbryUri.js +++ /dev/null @@ -1,85 +0,0 @@ -module.exports = { - REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g, - REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g, - REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/, - CHANNEL_CHAR : '@', - parseIdentifier : function (identifier) { - const componentsRegex = new RegExp( - '([^:$#/]*)' + // value (stops at the first separator or end) - '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) - ); - const [proto, value, modifierSeperator, modifier] = componentsRegex // eslint-disable-line no-unused-vars - .exec(identifier) - .map(match => match || null); - - // Validate and process name - if (!value) { - throw new Error(`Check your URL. No channel name provided before "${modifierSeperator}"`); - } - const isChannel = value.startsWith(module.exports.CHANNEL_CHAR); - const channelName = isChannel ? value : null; - let claimId; - if (isChannel) { - if (!channelName) { - throw new Error('Check your URL. No channel name after "@".'); - } - const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL); - if (nameBadChars) { - throw new Error(`Check your URL. Invalid characters in channel name: "${nameBadChars.join(', ')}".`); - } - } else { - claimId = value; - } - - // Validate and process modifier - let channelClaimId; - if (modifierSeperator) { - if (!modifier) { - throw new Error(`Check your URL. No modifier provided after separator "${modifierSeperator}"`); - } - - if (modifierSeperator === ':') { - channelClaimId = modifier; - } else { - throw new Error(`Check your URL. The "${modifierSeperator}" modifier is not currently supported`); - } - } - return { - isChannel, - channelName, - channelClaimId: channelClaimId || null, - claimId : claimId || null, - }; - }, - parseClaim: function (name) { - const componentsRegex = new RegExp( - '([^:$#/.]*)' + // name (stops at the first extension) - '([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end) - ); - const [proto, claimName, extensionSeperator, extension] = componentsRegex // eslint-disable-line no-unused-vars - .exec(name) - .map(match => match || null); - - // Validate and process name - if (!claimName) { - throw new Error('Check your URL. No claim name provided before "."'); - } - const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM); - if (nameBadChars) { - throw new Error(`Check your URL. Invalid characters in claim name: "${nameBadChars.join(', ')}".`); - } - // Validate and process extension - if (extensionSeperator) { - if (!extension) { - throw new Error(`Check your URL. No file extension provided after separator "${extensionSeperator}".`); - } - if (extensionSeperator !== '.') { - throw new Error(`Check your URL. The "${extensionSeperator}" separator is not supported in the claim name.`); - } - } - return { - claimName, - extension: extension || null, - }; - }, -}; diff --git a/server/controllers/api/oEmbed/index.js b/server/controllers/api/oEmbed/index.js index d068a4c7..690b1fa0 100644 --- a/server/controllers/api/oEmbed/index.js +++ b/server/controllers/api/oEmbed/index.js @@ -1,5 +1,5 @@ const logger = require('winston'); -const lbryUri = require('../../utils/lbryUri'); +const lbryUri = require('../../../../utils/lbryUri'); const getOEmbedDataForChannel = require('./getOEmbedDataForChannel'); const getOEmbedDataForAsset = require('./getOEmbedDataForAsset'); diff --git a/server/controllers/assets/serveByClaim/index.js b/server/controllers/assets/serveByClaim/index.js index 33614e39..a2b091a9 100644 --- a/server/controllers/assets/serveByClaim/index.js +++ b/server/controllers/assets/serveByClaim/index.js @@ -3,7 +3,7 @@ const logger = require('winston'); const { sendGAServeEvent } = require('../../../utils/googleAnalytics'); const handleShowRender = require('../../../render/build/handleShowRender.js'); -const lbryUri = require('../../utils/lbryUri.js'); +const lbryUri = require('../../../../utils/lbryUri.js'); const determineRequestType = require('../utils/determineRequestType.js'); const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js'); diff --git a/server/controllers/assets/serveByIdentifierAndClaim/index.js b/server/controllers/assets/serveByIdentifierAndClaim/index.js index 4b7b3469..521974a0 100644 --- a/server/controllers/assets/serveByIdentifierAndClaim/index.js +++ b/server/controllers/assets/serveByIdentifierAndClaim/index.js @@ -3,7 +3,7 @@ const logger = require('winston'); const { sendGAServeEvent } = require('../../../utils/googleAnalytics'); const handleShowRender = require('../../../render/build/handleShowRender.js'); -const lbryUri = require('../../utils/lbryUri.js'); +const lbryUri = require('../../../../utils/lbryUri.js'); const determineRequestType = require('../utils/determineRequestType.js'); const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js'); diff --git a/server/controllers/utils/lbryUri.js b/utils/lbryUri.js similarity index 83% rename from server/controllers/utils/lbryUri.js rename to utils/lbryUri.js index f72a25ef..697d630d 100644 --- a/server/controllers/utils/lbryUri.js +++ b/utils/lbryUri.js @@ -1,20 +1,16 @@ -const logger = require('winston'); - module.exports = { REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g, REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g, REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/, CHANNEL_CHAR : '@', parseIdentifier : function (identifier) { - logger.debug('parsing identifier:', identifier); const componentsRegex = new RegExp( '([^:$#/]*)' + // value (stops at the first separator or end) '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) ); - const [proto, value, modifierSeperator, modifier] = componentsRegex + const [, value, modifierSeperator, modifier] = componentsRegex .exec(identifier) .map(match => match || null); - logger.debug(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`); // Validate and process name if (!value) { @@ -56,15 +52,13 @@ module.exports = { }; }, parseClaim: function (claim) { - logger.debug('parsing name:', claim); const componentsRegex = new RegExp( '([^:$#/.]*)' + // name (stops at the first modifier) '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) ); - const [proto, claimName, modifierSeperator, modifier] = componentsRegex + const [, claimName, modifierSeperator, modifier] = componentsRegex .exec(claim) .map(match => match || null); - logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`); // Validate and process name if (!claimName) { @@ -86,18 +80,18 @@ module.exports = { // return results return { claimName, + extension: modifier || null, }; }, parseModifier: function (claim) { - logger.debug('parsing modifier:', claim); const componentsRegex = new RegExp( '([^:$#/.]*)' + // name (stops at the first modifier) '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) ); - const [proto, claimName, modifierSeperator, modifier] = componentsRegex + const [ , , modifierSeperator ] = componentsRegex .exec(claim) .map(match => match || null); - logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`); + // Validate and process modifier let hasFileExtension = false; if (modifierSeperator) { From e2a3039e4e30c10be2d90c3857a128e7ff7933d7 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Thu, 2 Aug 2018 15:54:23 -0700 Subject: [PATCH 3/3] set height on new publishes to current height in Claim db --- package.json | 1 + .../parsePublishApiRequestBody.test.js | 15 ++++ .../parsePublishApiRequestFiles.test.js | 51 +++++++++++++ server/models/claim.js | 5 ++ server/models/utils/createClaimRecordData.js | 35 +++++---- server/models/utils/returnShortId.test.js | 42 +++++++++++ ...end-to-end.tests.js => end-to-end.test.js} | 2 + test/module-alias-boilerplate.js | 4 ++ test/unit/publish/utils.test.js | 72 ------------------- utils/createModuleAliases.js | 1 + 10 files changed, 141 insertions(+), 87 deletions(-) create mode 100644 server/controllers/api/claim/publish/parsePublishApiRequestBody.test.js create mode 100644 server/controllers/api/claim/publish/parsePublishApiRequestFiles.test.js create mode 100644 server/models/utils/returnShortId.test.js rename test/end-to-end/{end-to-end.tests.js => end-to-end.test.js} (99%) create mode 100644 test/module-alias-boilerplate.js delete mode 100644 test/unit/publish/utils.test.js diff --git a/package.json b/package.json index dac711c3..1da071dd 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "start:build": "builder run start", "test": "mocha --recursive", "test:no-lbc": "npm test -- --grep @usesLbc --invert", + "test:server": "mocha --recursive './server/**/*.test.js'", "transpile": "builder concurrent transpile:server transpile:client transpile:client_custom", "transpile:dev": "builder concurrent transpile:server:dev transpile:client:dev transpile:client_custom:dev", "transpile:server": "babel server/render/src -d server/render/build", diff --git a/server/controllers/api/claim/publish/parsePublishApiRequestBody.test.js b/server/controllers/api/claim/publish/parsePublishApiRequestBody.test.js new file mode 100644 index 00000000..e1a43c99 --- /dev/null +++ b/server/controllers/api/claim/publish/parsePublishApiRequestBody.test.js @@ -0,0 +1,15 @@ +const chai = require('chai'); +const expect = chai.expect; + +describe('#parsePublishApiRequestBody()', function () { + const parsePublishApiRequestBody = require('./parsePublishApiRequestBody.js'); + + it('should throw an error if no body', function () { + expect(parsePublishApiRequestBody.bind(this, null)).to.throw(); + }); + + it('should throw an error if no body.name', function () { + const bodyNoName = {}; + expect(parsePublishApiRequestBody.bind(this, bodyNoName)).to.throw(); + }); +}); diff --git a/server/controllers/api/claim/publish/parsePublishApiRequestFiles.test.js b/server/controllers/api/claim/publish/parsePublishApiRequestFiles.test.js new file mode 100644 index 00000000..2eb7733d --- /dev/null +++ b/server/controllers/api/claim/publish/parsePublishApiRequestFiles.test.js @@ -0,0 +1,51 @@ +const chai = require('chai'); +const expect = chai.expect; + +describe('#parsePublishApiRequestFiles()', function () { + const parsePublishApiRequestFiles = require('./parsePublishApiRequestFiles.js'); + + it('should throw an error if no files', function () { + expect(parsePublishApiRequestFiles.bind(this, null)).to.throw(); + }); + + it('should throw an error if no files.file', function () { + const filesNoFile = {}; + expect(parsePublishApiRequestFiles.bind(this, filesNoFile)).to.throw(); + }); + + it('should throw an error if file.size is too large', function () { + const filesTooBig = { + file: { + name: 'file.jpg', + path: '/path/to/file.jpg', + type: 'image/jpg', + size: 10000001, + }, + }; + expect(parsePublishApiRequestFiles.bind(this, filesTooBig)).to.throw(); + }); + + it('should throw error if not an accepted file type', function () { + const filesWrongType = { + file: { + name: 'file.jpg', + path: '/path/to/file.jpg', + type: 'someType/ext', + size: 10000000, + }, + }; + expect(parsePublishApiRequestFiles.bind(this, filesWrongType)).to.throw(); + }); + + it('should throw NO error if no problems', function () { + const filesNoProblems = { + file: { + name: 'file.jpg', + path: '/path/to/file.jpg', + type: 'image/jpg', + size: 10000000, + }, + }; + expect(parsePublishApiRequestFiles.bind(this, filesNoProblems)).to.not.throw(); + }); +}); diff --git a/server/models/claim.js b/server/models/claim.js index 2fa6edc6..08bd7c6b 100644 --- a/server/models/claim.js +++ b/server/models/claim.js @@ -401,5 +401,10 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => { }); }; + Claim.getCurrentHeight = function () { + return this + .max('height'); + }; + return Claim; }; diff --git a/server/models/utils/createClaimRecordData.js b/server/models/utils/createClaimRecordData.js index 91e25ca3..547b6158 100644 --- a/server/models/utils/createClaimRecordData.js +++ b/server/models/utils/createClaimRecordData.js @@ -1,3 +1,5 @@ +const db = require('../index.js'); + const createClaimRecordDataAfterPublish = (certificateId, channelName, fileName, fileType, publishParams, publishResults) => { const { name, @@ -17,21 +19,24 @@ const createClaimRecordDataAfterPublish = (certificateId, channelName, fileName, nout, } = publishResults; - return { - name, - claimId, - title, - description, - address, - thumbnail, - outpoint : `${txid}:${nout}`, - height : 0, - contentType: fileType, - nsfw, - amount, - certificateId, - channelName, - }; + return db.Claim.getCurrentHeight() + .then(height => { + return { + name, + claimId, + title, + description, + address, + thumbnail, + outpoint : `${txid}:${nout}`, + height, + contentType: fileType, + nsfw, + amount, + certificateId, + channelName, + }; + }); }; module.exports = { diff --git a/server/models/utils/returnShortId.test.js b/server/models/utils/returnShortId.test.js new file mode 100644 index 00000000..56b8cbb9 --- /dev/null +++ b/server/models/utils/returnShortId.test.js @@ -0,0 +1,42 @@ +const chai = require('chai'); +const expect = chai.expect; + +describe('#parsePublishApiRequestBody()', function () { + const returnShortId = require('./returnShortId.js'); + let dummyClaimsArray; + let dummyLongId; + + it('should thow an error if the claimId is not in the claim list', function () { + dummyClaimsArray = [ + {claimId: 'a123456789'}, + {claimId: 'b123456789'}, + {claimId: 'c123456789'}, + ]; + dummyLongId = 'xxxxxxxxxx'; + expect(returnShortId.bind(this, dummyClaimsArray, dummyLongId)).to.throw(); + }); + + it('should return the shortest unique claim id', function () { + dummyClaimsArray = [ + {claimId: 'a123456789'}, + {claimId: 'b123456789'}, + {claimId: 'c123456789'}, + ]; + dummyLongId = 'c123456789'; + expect(returnShortId(dummyClaimsArray, dummyLongId)).to.equal('c'); + }); + + it('if there is a conflict between unqiue ids, it should give preference to the one with the lowest height', function () { + dummyClaimsArray = [ + {claimId: 'a123456789', height: 10}, + {claimId: 'ab12345678', height: 11}, + {claimId: 'ab12341111', height: 12}, + ]; + dummyLongId = 'a123456789'; + expect(returnShortId(dummyClaimsArray, dummyLongId)).to.equal('a'); + dummyLongId = 'ab12345678'; + expect(returnShortId(dummyClaimsArray, dummyLongId)).to.equal('ab'); + dummyLongId = 'ab12341111'; + expect(returnShortId(dummyClaimsArray, dummyLongId)).to.equal('ab12341'); + }); +}); diff --git a/test/end-to-end/end-to-end.tests.js b/test/end-to-end/end-to-end.test.js similarity index 99% rename from test/end-to-end/end-to-end.tests.js rename to test/end-to-end/end-to-end.test.js index ee055b0a..4c6f2e35 100644 --- a/test/end-to-end/end-to-end.tests.js +++ b/test/end-to-end/end-to-end.test.js @@ -1,3 +1,5 @@ +require('../module-alias-boilerplate.js'); + const chai = require('chai'); const expect = chai.expect; const chaiHttp = require('chai-http'); diff --git a/test/module-alias-boilerplate.js b/test/module-alias-boilerplate.js new file mode 100644 index 00000000..1001e4be --- /dev/null +++ b/test/module-alias-boilerplate.js @@ -0,0 +1,4 @@ +// set up aliases +const moduleAlias = require('module-alias'); +const customAliases = require('../utils/createModuleAliases.js')(); +moduleAlias.addAliases(customAliases); diff --git a/test/unit/publish/utils.test.js b/test/unit/publish/utils.test.js deleted file mode 100644 index 4d8aac20..00000000 --- a/test/unit/publish/utils.test.js +++ /dev/null @@ -1,72 +0,0 @@ -const chai = require('chai'); -const expect = chai.expect; - -describe('publish utils', function () { - - describe('#parsePublishApiRequestBody()', function () { - const parsePublishApiRequestBody = require('../../../server/controllers/api/claim/publish/parsePublishApiRequestBody.js'); - - it('should throw an error if no body', function () { - expect(parsePublishApiRequestBody.bind(this, null)).to.throw(); - }); - - it('should throw an error if no body.name', function () { - const bodyNoName = {}; - expect(parsePublishApiRequestBody.bind(this, bodyNoName)).to.throw(); - }); - - }); - - describe('#parsePublishApiRequestFiles()', function () { - const parsePublishApiRequestFiles = require('../../../server/controllers/api/claim/publish/parsePublishApiRequestFiles.js'); - - it('should throw an error if no files', function () { - expect(parsePublishApiRequestFiles.bind(this, null)).to.throw(); - }); - - it('should throw an error if no files.file', function () { - const filesNoFile = {}; - expect(parsePublishApiRequestFiles.bind(this, filesNoFile)).to.throw(); - }); - - it('should throw an error if file.size is too large', function () { - const filesTooBig = { - file: { - name: 'file.jpg', - path: '/path/to/file.jpg', - type: 'image/jpg', - size: 10000001, - }, - }; - expect(parsePublishApiRequestFiles.bind(this, filesTooBig)).to.throw(); - }); - - it('should throw error if not an accepted file type', function () { - const filesWrongType = { - file: { - name: 'file.jpg', - path: '/path/to/file.jpg', - type: 'someType/ext', - size: 10000000, - }, - }; - expect(parsePublishApiRequestFiles.bind(this, filesWrongType)).to.throw(); - }); - - it('should throw NO error if no problems', function () { - const filesNoProblems = { - file: { - name: 'file.jpg', - path: '/path/to/file.jpg', - type: 'image/jpg', - size: 10000000, - }, - }; - expect(parsePublishApiRequestFiles.bind(this, filesNoProblems)).to.not.throw(); - }); - }); - - describe('#parsePublishApiChannel()', function () { - it('should pass the tests I write here'); - }); -}); diff --git a/utils/createModuleAliases.js b/utils/createModuleAliases.js index 036c56e3..7a494bf6 100644 --- a/utils/createModuleAliases.js +++ b/utils/createModuleAliases.js @@ -26,6 +26,7 @@ module.exports = () => { let moduleAliases = {}; // aliases for configs moduleAliases['@config'] = resolve(`config`); + moduleAliases['@devConfig'] = resolve(`devConfig`); // create specific aliases for locally defined components moduleAliases = addAlliasesForFolder('containers', moduleAliases);