Commit 104ca992 authored by Alexandros Georgantas's avatar Alexandros Georgantas

Merge branch 'custom-tags' into 'master'

Custom tags

See merge request editoria/editoria!143
parents bd129f51 222ce149
module.exports = {
collectCoverage: false,
collectCoverageFrom: [
'**/*.{js,jsx}',
'!**/*test.{js,jsx}',
'!**/test/**',
'!**/node_modules/**',
'!**/config/**',
'!**/coverage/**',
],
coverageDirectory: '<rootDir>/coverage',
projects: [
'<rootDir>/packages/data-model/jest.config.js',
'<rootDir>/packages/api/jest.config.js',
],
}
......@@ -2,10 +2,11 @@
"author": "Yannis Barlas, Alexandros Georgantas",
"description": "Monorepo grouping all the different parts of the Editoria project",
"devDependencies": {
"babel-eslint": "^8.0.3",
"babel-preset-es2015": "^6.24.1",
"@commitlint/cli": "^6.0.5",
"@commitlint/config-conventional": "^6.0.4",
"babel-eslint": "^8.0.3",
"babel-jest": "^24.8.0",
"babel-preset-es2015": "^6.24.1",
"commitizen": "^2.9.6",
"cz-conventional-changelog": "^2.1.0",
"eslint": "^4.13.1",
......@@ -18,16 +19,17 @@
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-react": "^7.4.0",
"eslint-plugin-standard": "^3.0.1",
"jest": "^24.8.0",
"lerna": "^2.5.1",
"lint-staged": "^6.0.0",
"prettier": "^1.8.2",
"standard-version": "^4.4.0",
"style-loader": "^0.21.0",
"stylelint": "^9.2.1",
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-order": "^1.0.0",
"stylelint-processor-styled-components": "^1.3.1",
"standard-version": "^4.4.0"
"stylelint-processor-styled-components": "^1.3.1"
},
"license": "MIT",
"name": "editoria-monorepo",
......@@ -60,7 +62,12 @@
"babel-preset-stage-0": "^6.24.1"
},
"workspaces": {
"packages": ["packages/*"],
"nohoist": ["**/react-adopt", "**/react-powerplug"]
"packages": [
"packages/*"
],
"nohoist": [
"**/react-adopt",
"**/react-powerplug"
]
}
}
module.exports = {
user: {
type: 'user',
username: 'testuser',
email: 'test@example.com',
password: 'test',
},
addTag: [
{
tagType: 'block',
label: 'tag1',
},
{
tagType: 'inline',
label: 'tag2',
},
],
updateTag: [
{
tagType: 'inline',
label: 'tag1new',
},
],
}
const { CustomTag } = require('editoria-data-model/src').models
const omit = require('lodash/omit')
const pick = require('lodash/pick')
const map = require('lodash/map')
const {
editoriaDataModel: {
models: { User },
},
} = require('editoria-data-model')
const { dbCleaner, api } = require('pubsweet-server/test')
const fixtures = require('./helpers/fixtures')
const authentication = require('pubsweet-server/src/authentication')
describe('Tag mutations', () => {
// let token
// let user
beforeEach(async () => {
await dbCleaner()
})
it('can add a custom tag', async () => {
const user = await new User(fixtures.user).save()
const token = authentication.token.create(user)
const {
body: {
data: { addCustomTag },
},
} = await api.graphql.query(
`mutation($input: [CustomTagAddInput]!) {
addCustomTag(input: $input) {
id
label
tagType
}
}`,
{
input: fixtures.addTag,
},
token,
)
expect(map(addCustomTag, tag => omit(tag, ['id']))).toEqual(fixtures.addTag)
})
it('can update a custom tag', async () => {
const user = await new User(fixtures.user).save()
const token = authentication.token.create(user)
const customTag = await Promise.all(
fixtures.addTag.map(async tag => {
const addTag = await new CustomTag(tag).save()
return addTag
}),
)
fixtures.updateTag[0].id = customTag[0].id
const {
body: {
data: { updateCustomTag },
},
} = await api.graphql.query(
`mutation($input: [CustomTagUpdateInput]!) {
updateCustomTag(input: $input) {
id
label
tagType
}
}`,
{
input: fixtures.updateTag,
},
token,
)
const resultTag = [fixtures.addTag[1], fixtures.updateTag[0]]
const compareCustomTag = map(updateCustomTag, tag =>
pick(tag, ['label', 'tagType']),
)
expect(compareCustomTag).toEqual(map(resultTag, tag => omit(tag, ['id'])))
})
it('can delete a custom tag', async () => {
const user = await new User(fixtures.user).save()
const token = authentication.token.create(user)
const customTag = await Promise.all(
fixtures.addTag.map(async tag => {
const addTag = await new CustomTag(tag).save()
return addTag
}),
)
const deleteTag = {
id: customTag[0].id,
deleted: true,
}
const {
body: {
data: { updateCustomTag },
},
} = await api.graphql.query(
`mutation($input: [CustomTagUpdateInput]!) {
updateCustomTag(input: $input) {
id
label
tagType
}
}`,
{
input: [deleteTag],
},
token,
)
const compareCustomTag = map(customTag, tag =>
pick(tag, ['id', 'label', 'tagType']),
)
expect(updateCustomTag).toEqual([compareCustomTag[1]])
})
})
export DB_PORT='5460'
export DB_NAME='editoria_test'
export DB_USER='test'
export DB_PASSWORD='secretpassword'
......@@ -4,11 +4,10 @@ const winston = require('winston')
module.exports = {
'pubsweet-server': {
db: {
// database: 'test',
port: 5499,
user: 'testuser',
password: 'testpass',
database: global.__testDbName || 'test',
port: 5460,
user: 'test',
password: 'secretpassword',
database: global.__testDbName || 'editoria_test',
},
enableExperimentalGraphql: true,
logger: new winston.Logger({
......@@ -24,6 +23,14 @@ module.exports = {
sse: false,
uploads: 'uploads',
},
pubsweet: {
components: [
'@pubsweet/model-user',
'@pubsweet/model-team',
'./customTag',
'editoria-data-model/src/customTag',
],
},
authsome: {
mode: path.resolve(__dirname, 'auth'),
teams: {
......@@ -32,11 +39,4 @@ module.exports = {
},
},
},
schema: {
Manuscript: {
properties: {
configField: { type: 'string' },
},
},
},
}
const BOOK_COMPONENT_ADDED = 'BOOK_COMPONENT_ADDED'
const BOOK_COMPONENT_DELETED = 'BOOK_COMPONENT_DELETED'
const BOOK_COMPONENT_WORKFLOW_UPDATED = 'BOOK_COMPONENT_WORKFLOW_UPDATED'
const BOOK_COMPONENT_PAGINATION_UPDATED = 'BOOK_COMPONENT_PAGINATION_UPDATED'
const BOOK_COMPONENT_TRACK_CHANGES_UPDATED =
'BOOK_COMPONENT_TRACK_CHANGES_UPDATED'
const BOOK_COMPONENT_TITLE_UPDATED = 'BOOK_COMPONENT_TITLE_UPDATED'
const BOOK_COMPONENT_CONTENT_UPDATED = 'BOOK_COMPONENT_CONTENT_UPDATED'
const BOOK_COMPONENT_UPLOADING_UPDATED = 'BOOK_COMPONENT_UPLOADING_UPDATED'
const BOOK_COMPONENT_LOCK_UPDATED = 'BOOK_COMPONENT_LOCK_UPDATED'
const BOOK_COMPONENT_TYPE_UPDATED = 'BOOK_COMPONENT_TYPE_UPDATED'
module.exports = {
BOOK_COMPONENT_ADDED,
BOOK_COMPONENT_DELETED,
BOOK_COMPONENT_WORKFLOW_UPDATED,
BOOK_COMPONENT_PAGINATION_UPDATED,
BOOK_COMPONENT_TRACK_CHANGES_UPDATED,
BOOK_COMPONENT_TITLE_UPDATED,
BOOK_COMPONENT_CONTENT_UPDATED,
BOOK_COMPONENT_UPLOADING_UPDATED,
BOOK_COMPONENT_LOCK_UPDATED,
BOOK_COMPONENT_TYPE_UPDATED,
}
type CustomTag {
id: ID!
label: String!
tagType: String!
}
input CustomTagUpdateInput {
id: ID!
label: String
tagType: String
deleted: Boolean
}
input CustomTagAddInput {
label: String
tagType: String
}
extend type Query {
getCustomTags: [CustomTag]!
}
extend type Mutation {
addCustomTag(input: [CustomTagAddInput]!): [CustomTag]!
updateCustomTag(input: [CustomTagUpdateInput]!): [CustomTag]!
}
const logger = require('@pubsweet/logger')
const { CustomTag } = require('editoria-data-model/src').models
const getCustomTags = async (_, input, ctx) => {
const customTags = await CustomTag.query().where({ deleted: false })
if (!customTags) {
throw new Error(`CustomTags error: Could not fetch Tags`)
}
return customTags
}
const addCustomTag = async (_, { input }, ctx) => {
try {
await Promise.all(
input.map(async tag => {
const { label, tagType } = tag
await new CustomTag({ label, tagType }).save()
}),
)
const customTags = await CustomTag.query().where({ deleted: false })
return customTags
} catch (e) {
logger.error(e)
throw new Error(e)
}
}
const updateCustomTag = async (_, { input }, ctx) => {
try {
await Promise.all(
input.map(async tag => {
const { id, deleted, tagType, label } = tag
await CustomTag.query().patchAndFetchById(id, {
label,
deleted,
tagType,
})
}),
)
logger.info(`Custom Tag component with id ${updateCustomTag.id} deleted`)
const customTags = await CustomTag.query().where({ deleted: false })
return customTags
} catch (e) {
logger.error(e)
throw new Error(e)
}
}
module.exports = {
Query: {
getCustomTags,
},
Mutation: {
addCustomTag,
updateCustomTag,
},
}
const models = require('editoria-data-model')
module.exports = {
resolvers: require('./customTag.resolvers'),
typeDefs: require('../graphqlLoaderUtil')('customTag/customTag.graphql'),
model: models.customTag,
}
......@@ -2,6 +2,7 @@ const authorize = require('./authorize')
const book = require('./book')
const bookComponent = require('./bookComponent')
const bookCollection = require('./bookCollection')
const customTag = require('./customTag')
const division = require('./division')
const team = require('./team')
const user = require('./user')
......@@ -18,6 +19,7 @@ module.exports = {
book.typeDefs,
bookComponent.typeDefs,
bookCollection.typeDefs,
customTag.typeDefs,
division.typeDefs,
file.typeDefs,
team.typeDefs,
......@@ -29,6 +31,7 @@ module.exports = {
book.resolvers,
bookComponent.resolvers,
bookCollection.resolvers,
customTag.resolvers,
division.resolvers,
file.resolvers,
team.resolvers,
......
module.exports = {
displayName: 'api',
testEnvironment: 'jest-environment-db',
testRegex: '.*test.js$',
testPathIgnorePatterns: [
'./config',
'./__tests__/helpers',
'./node_modules/',
],
}
......@@ -8,6 +8,9 @@
"pubsweet-component",
"graphql"
],
"scripts": {
"test": "jest"
},
"author": "Alexandros Georgantas",
"license": "ISC",
"dependencies": {
......
......@@ -5,8 +5,7 @@
"main": "index.js",
"scripts": {
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build",
"test": "echo \"Error: no test specified\" && exit 1"
"styleguide:build": "styleguidist build"
},
"keywords": [
"pubsweet-component",
......
......@@ -3,9 +3,6 @@
"version": "0.1.6",
"description": "Common react components for the editoria project",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
......
......@@ -4,7 +4,7 @@
"description": "The application dashboard for the Editoria project.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\""
},
"keywords": [
"pubsweet-component",
......
const registerComponents = require('./helpers/registerComponents')
registerComponents(['book', 'bookCollection', 'division'])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
const config = require('config')
const set = require('lodash/set')
// const set = require('lodash/set')
const unset = require('lodash/unset')
const { Book, BookCollection, Division } = require('../src').models
......@@ -16,7 +13,7 @@ describe('Book', () => {
it('can add books', async () => {
const divisionId = uuid()
const publicationDate = new Date()
const publicationDate = new Date().toString()
let collectionId
await new BookCollection().save().then(res => (collectionId = res.id))
......@@ -40,16 +37,10 @@ describe('Book', () => {
})
it('creates divisions on book creation based on the config', async () => {
set(config, 'bookBuilder.divisions', [
{ name: 'front' },
{ name: 'body' },
{ name: 'back' },
])
const collection = await new BookCollection().save()
const book = await new Book({ collectionId: collection.id }).save()
const divisions = await Division.query().where('bookId', book.id)
const divisions = await Division.query().where('bookId', book.id)
expect(divisions).toHaveLength(3)
expect(book.divisions).toHaveLength(3)
......@@ -66,11 +57,10 @@ describe('Book', () => {
const actualPosition = book.divisions.indexOf(division.id)
expect(actualPosition).toBe(correctPosition)
})
unset(config, 'bookBuilder')
})
it('creates a default division on book creation if no config is found', async () => {
unset(config, 'bookBuilder')
const collection = await new BookCollection().save()
const book = await new Book({ collectionId: collection.id }).save()
const divisions = await Division.query().where('bookId', book.id)
......
const registerComponents = require('./helpers/registerComponents')
registerComponents(['book', 'bookCollection'])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
const { Book, BookCollection } = require('../src').models
......
const registerComponents = require('./helpers/registerComponents')
registerComponents(['bookCollection', 'bookCollectionTranslation'])
const { dbCleaner } = require('pubsweet-server/test')
const { BookCollection, BookCollectionTranslation } = require('../src').models
......
const registerComponents = require('./helpers/registerComponents')
registerComponents(['book', 'bookCollection', 'bookComponent', 'division'])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
const {
......
const registerComponents = require('./helpers/registerComponents')
registerComponents([
'book',
'bookCollection',
'bookComponent',
'bookComponentState',
'division',
])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
......
const registerComponents = require('./helpers/registerComponents')
registerComponents([
'book',
'bookCollection',
'bookComponent',
'bookComponentTranslation',
'division',
])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
......
const registerComponents = require('./helpers/registerComponents')
registerComponents(['book', 'bookTranslation', 'bookCollection'])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
......
const path = require('path')
process.env.NODE_CONFIG_DIR = path.resolve(__dirname)
export DB_PORT='5499'
export DB_NAME='test'
export DB_USER='testuser'
export DB_PASSWORD='testpass'
echo $DB_NAME
const registerComponents = require('./helpers/registerComponents')
registerComponents(['book', 'bookCollection', 'division'])
const uuid = require('uuid/v4')
const { dbCleaner } = require('pubsweet-server/test')
const { Book, BookCollection, Division } = require('../src').models
......
const path = require('path')
/*
Registers an array of components on pubsweet's config, so that the migrations
are ran. Will treat a string as a single component.
Valid input examples:
- ['book', 'bookCollection']
- 'book'
Only works for this package, as it assumes a specific structure to locate
the different models.
*/
const registerComponents = componentNames => {
let components = componentNames
const paths = []
if (typeof componentNames === 'string') {
components = [componentNames]
} else if (!Array.isArray(componentNames)) {
throw new Error('Component names need to be an array or a string')
}
components.forEach(comp => {
const componentPath = path.resolve(__dirname, '..', '..', 'src', comp)
paths.push(componentPath)
})
const toString = paths.map(p => `"${p}"`).join(', ')
// console.log(`{"pubsweet":{"components":[${toString}]}}`)
// return `{"pubsweet":{"components":[${toString}]}}`
process.env.NODE_CONFIG = `{"pubsweet":{"components":[${toString}]}}`
}
module.exports = registerComponents
const { User } = require('pubsweet-server')
const registerComponents = require('./helpers/registerComponents')
registerComponents(['bookCollection', 'lock'])
const {
editoriaDataModel: {
models: { User },
},
} = require('editoria-data-model')
const { BookCollection, Lock } = require('editoria-data-model/src').models
const { dbCleaner } = require('pubsweet-server/test')
const { BookCollection, Lock } = require('../src').models
let collection, user
describe('Lock', () => {
......
const auth = () => true
module.exports = auth
export DB_PORT='5460'
export DB_NAME='editoria_test'
export DB_USER='test'
export DB_PASSWORD='secretpassword'
export ALLOW_CONFIG_MUTATIONS=true
const path = require('path')
const winston = require('winston')
module.exports = {
'pubsweet-server': {
db: {
port: 5460,
user: 'test',
password: 'secretpassword',
database: global.__testDbName || 'editoria_test',
},
enableExperimentalGraphql: true,
logger: new winston.Logger({
transports: [
new winston.transports.Console({
colorize: true,
}),
],
}),
pool: { min: 0, max: 10, idleTimeoutMillis: 1000 },
port: 4000,
secret: 'test',
sse: false,
uploads: 'uploads',
},
authsome: {
mode: path.resolve(__dirname, 'auth'),
teams: {
teamTest: {
name: 'Contributors',
},
},