first attempt to automate dynamic seeding

This commit is contained in:
Grzegorz Leoniec 2018-11-16 20:59:05 +01:00
parent 59e9b9df1d
commit 96da90a255
7 changed files with 276 additions and 7 deletions

View File

@ -37,17 +37,19 @@ const isModerator = rule()(async (parent, args, ctx, info) => {
// Permissions
const permissions = shield({
Query: {
statistics: isAdmin
statistics: isAdmin,
// fruits: and(isAuthenticated, or(isAdmin, isModerator)),
// customers: and(isAuthenticated, isAdmin)
},
Mutation: {
// addFruitToBasket: isAuthenticated
CreateUser: allow
},
User: {
email: isOwner,
password: isOwner
},
// TODO: re-activate this after fixing the initial seed
// User: {
// email: isOwner,
// password: isOwner
// },
Post: isAuthenticated
})

12
src/seed/data/badges.js Normal file
View File

@ -0,0 +1,12 @@
export default function (data) {
return `
mutation {
b1: CreateBadge(id: "b1", key: "indiegogo_en_racoon", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_racoon.svg") { id }
b2: CreateBadge(id: "b2", key: "indiegogo_en_rabbit", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rabbit.svg") { id }
b3: CreateBadge(id: "b3", key: "indiegogo_en_wolf", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_wolf.svg") { id }
b4: CreateBadge(id: "b4", key: "indiegogo_en_bear", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_bear.svg") { id }
b5: CreateBadge(id: "b5", key: "indiegogo_en_turtle", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_turtle.svg") { id }
b6: CreateBadge(id: "b6", key: "indiegogo_en_rhino", type: crowdfunding, status: permanent, icon: "http://localhost:3000/img/badges/indiegogo_en_rhino.svg") { id }
}
`
}

27
src/seed/data/index.js Normal file
View File

@ -0,0 +1,27 @@
import gql from 'graphql-tag'
import helper from '../seed-helpers'
const seed = {
Badges: require('./badges.js').default,
User: require('./users.js').default,
UserBadges: require('./users-badges.js').default
};
let data = {}
export default async function (client) {
// iterate through seeds
await helper.asyncForEach(Object.keys(seed), async key => {
const mutations = seed[key]
try {
const res = await client
.mutate({
mutation: gql(mutations(data))
})
data[key] = Object.assign(data[key] || {}, res.data)
} catch (err) {
console.error(err)
}
})
console.log('Seeded Data', data)
}

View File

@ -0,0 +1,12 @@
export default function (data) {
return `
mutation {
b1_u1: AddUserBadges(from: {id: "b1"}, to: {id: "u1"}) { from { id } }
b2_u1: AddUserBadges(from: {id: "b2"}, to: {id: "u1"}) { from { id } }
b3_u1: AddUserBadges(from: {id: "b3"}, to: {id: "u1"}) { from { id } }
b6_u2: AddUserBadges(from: {id: "b6"}, to: {id: "u2"}) { from { id } }
b3_u3: AddUserBadges(from: {id: "b3"}, to: {id: "u3"}) { from { id } }
b5_u4: AddUserBadges(from: {id: "b5"}, to: {id: "u4"}) { from { id } }
}
`
}

68
src/seed/data/users.js Normal file
View File

@ -0,0 +1,68 @@
import faker from 'faker'
export default function (data) {
return `
mutation {
u1: CreateUser(
id: "u1",
name: "Peter Lustig",
password: "1234",
email: "admin@example.org",
avatar: "${faker.internet.avatar()}",
role: admin,
disabled: false,
deleted: false) {
id
name
email
avatar
role
}
u2: CreateUser(
id: "u2",
name: "Bob der Bausmeister",
password: "1234",
email: "moderator@example.org",
avatar: "${faker.internet.avatar()}",
role: moderator,
disabled: false,
deleted: false) {
id
name
email
avatar
role
}
u3: CreateUser(
id: "u3",
name: "Jenny Rostock",
password: "1234",
email: "user@example.org",
avatar: "${faker.internet.avatar()}",
role: user,
disabled: false,
deleted: false) {
id
name
email
avatar
role
}
u4: CreateUser(
id: "u4",
name: "Angie Banjie",
password: "1234",
email: "angie@example.org",
avatar: "${faker.internet.avatar()}",
role: user,
disabled: false,
deleted: false) {
id
name
email
avatar
role
}
}
`
}

View File

@ -5,6 +5,7 @@ import seedMutations from "./seed-mutations";
import fetch from "node-fetch";
import { HttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import Seed from './data/index'
dotenv.config();
@ -13,9 +14,11 @@ const client = new ApolloClient({
cache: new InMemoryCache()
});
client
Seed(client)
/* client
.mutate({
mutation: gql(seedMutations)
})
.then(data => console.log(data))
.catch(error => console.error(error));
.catch(error => console.error(error)); **/

145
src/seed/seed-helpers.js Normal file
View File

@ -0,0 +1,145 @@
const _ = require('lodash')
const faker = require('faker')
const unsplashTopics = [
'love',
'family',
'spring',
'business',
'nature',
'travel',
'happy',
'landscape',
'health',
'friends',
'computer',
'autumn',
'space',
'animal',
'smile',
'face',
'people',
'portrait',
'amazing'
]
let unsplashTopicsTmp = []
const ngoLogos = [
'http://www.fetchlogos.com/wp-content/uploads/2015/11/Girl-Scouts-Of-The-Usa-Logo.jpg',
'http://logos.textgiraffe.com/logos/logo-name/Ngo-designstyle-friday-m.png',
'http://seeklogo.com/images/N/ngo-logo-BD53A3E024-seeklogo.com.png',
'https://dcassetcdn.com/design_img/10133/25833/25833_303600_10133_image.jpg',
'https://cdn.tutsplus.com/vector/uploads/legacy/articles/08bad_ngologos/20.jpg',
'https://cdn.tutsplus.com/vector/uploads/legacy/articles/08bad_ngologos/33.jpg',
null
]
const difficulties = ['easy', 'medium', 'hard']
export default {
randomItem: (items, filter) => {
let ids = filter
? Object.keys(items)
.filter(id => {
return filter(items[id])
})
: _.keys(items)
let randomIds = _.shuffle(ids)
return items[randomIds.pop()]
},
randomItems: (items, key = '_id', min = 1, max = 1) => {
let randomIds = _.shuffle(_.keys(items))
let res = []
const count = _.random(min, max)
for (let i = 0; i < count; i++) {
let r = items[randomIds.pop()][key]
if (key === '_id') {
r = r.toString()
}
res.push(r)
}
return res
},
random: (items) => {
return _.shuffle(items).pop()
},
randomDifficulty: () => {
return _.shuffle(difficulties).pop()
},
randomLogo: () => {
return _.shuffle(ngoLogos).pop()
},
randomUnsplashUrl: () => {
if (Math.random() < 0.6) {
// do not attach images in 60 percent of the cases (faster seeding)
return
}
if (unsplashTopicsTmp.length < 2) {
unsplashTopicsTmp = _.shuffle(unsplashTopics)
}
return 'https://source.unsplash.com/daily?' + unsplashTopicsTmp.pop() + ',' + unsplashTopicsTmp.pop()
},
randomCategories: (seederstore, allowEmpty = false) => {
let count = Math.round(Math.random() * 3)
if (allowEmpty === false && count === 0) {
count = 1
}
let categorieIds = _.shuffle(_.keys(seederstore.categories))
let ids = []
for (let i = 0; i < count; i++) {
ids.push(categorieIds.pop())
}
return ids
},
randomAddresses: () => {
const count = Math.round(Math.random() * 3)
let addresses = []
for (let i = 0; i < count; i++) {
addresses.push({
city: faker.address.city(),
zipCode: faker.address.zipCode(),
street: faker.address.streetAddress(),
country: faker.address.countryCode(),
lat: 54.032726 - (Math.random() * 10),
lng: 6.558838 + (Math.random() * 10)
})
}
return addresses
},
/**
* Get array of ids from the given seederstore items after mapping them by the key in the values
*
* @param items items from the seederstore
* @param values values for which you need the ids
* @param key the field key that is represented in the values (slug, name, etc.)
*/
mapIdsByKey: (items, values, key) => {
let res = []
values.forEach(value => {
res.push(_.find(items, [key, value])._id.toString())
})
return res
},
/**
* Provide a way to iterate for each element in an array while waiting for async functions to finish
*
* @param array
* @param callback
* @returns {Promise<void>}
*/
asyncForEach: async (array, callback) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
},
genInviteCode: () => {
const chars = '23456789abcdefghkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ'
let code = ''
for (let i = 0; i < 8; i++) {
const n = _.random(0, chars.length-1)
code += chars.substr(n, 1)
}
return code
}
}