Improve mocking and debugging with web instance (#91)

This commit is contained in:
Simon Lecoq
2021-02-02 14:05:01 +01:00
committed by GitHub
parent 30956be7b0
commit b8182c4eb5
12 changed files with 40 additions and 36 deletions

View File

@@ -587,7 +587,7 @@ Add them in [`source/app/mocks/api/`](/source/app/mocks/api) folder.
If you're using `axios` or GitHub GraphQL API, these files are autoloaded so you just need to create new functions (see other mocked data for examples). If you're using `axios` or GitHub GraphQL API, these files are autoloaded so you just need to create new functions (see other mocked data for examples).
If you're using GitHub REST API, you'll also need to edit [`source/app/mocks/index.mjs`](/source/app/mocks/index.mjs) to add a new proxied method. If you're using GitHub REST API, add your mocks in [`source/app/mocks/rest`](/source/app/mocks/rest) with same path as octokit.
</details> </details>

View File

@@ -261,6 +261,7 @@
{ {
sha:"MOCKED_SHA", sha:"MOCKED_SHA",
message:faker.lorem.sentence(), message:faker.lorem.sentence(),
url:"https://api.github.com/repos/lowlighter/metrics/commits/MOCKED_SHA",
} }
] ]
}, },

View File

@@ -60,25 +60,20 @@
{ {
//Unmocked //Unmocked
console.debug(`metrics/compute/mocks > mocking rest api`) console.debug(`metrics/compute/mocks > mocking rest api`)
const unmocked = { const unmocked = {}
request:rest.request,
rateLimit:rest.rateLimit.get,
listEventsForAuthenticatedUser:rest.activity.listEventsForAuthenticatedUser,
getViews:rest.repos.getViews,
getContributorsStats:rest.repos.getContributorsStats,
listCommits:rest.repos.listCommits,
listContributors:rest.repos.listContributors,
getByUsername:rest.users.getByUsername,
}
//Mocked //Mocked
rest.request = new Proxy(unmocked.request, {apply:mocks.github.rest.raw.bind(null, {faker})}) const mocker = ({path = "rest", mocks, mocked}) => {
rest.rateLimit.get = new Proxy(unmocked.rateLimit, {apply:mocks.github.rest.ratelimit.bind(null, {faker})}) for (const [key, value] of Object.entries(mocks)) {
rest.activity.listEventsForAuthenticatedUser = new Proxy(unmocked.listEventsForAuthenticatedUser, {apply:mocks.github.rest.events.bind(null, {faker})}) console.debug(`metrics/compute/mocks > mocking rest api > mocking ${path}.${key}`)
rest.repos.getViews = new Proxy(unmocked.getViews, {apply:mocks.github.rest.views.bind(null, {faker})}) if (typeof value === "function") {
rest.repos.getContributorsStats = new Proxy(unmocked.getContributorsStats, {apply:mocks.github.rest.stats.bind(null, {faker})}) unmocked[path] = value
rest.repos.listCommits = new Proxy(unmocked.listCommits, {apply:mocks.github.rest.commits.bind(null, {faker})}) mocked[key] = new Proxy(unmocked[path], {apply:value.bind(null, {faker})})
rest.repos.listContributors = new Proxy(unmocked.listContributors, {apply:mocks.github.rest.contributors.bind(null, {faker})}) }
rest.users.getByUsername = new Proxy(unmocked.getByUsername, {apply:mocks.github.rest.username.bind(null, {faker})}) else
mocker({path:`${path}.${key}`, mocks:mocks[key], mocked:mocked[key]})
}
}
mocker({mocks:mocks.github.rest, mocked:rest})
} }
//Axios mocking //Axios mocking

View File

@@ -18,25 +18,32 @@
const {token, maxusers = 0, restricted = [], debug = false, cached = 30*60*1000, port = 3000, ratelimiter = null, plugins = null} = conf.settings const {token, maxusers = 0, restricted = [], debug = false, cached = 30*60*1000, port = 3000, ratelimiter = null, plugins = null} = conf.settings
mock = mock || conf.settings.mocked mock = mock || conf.settings.mocked
//Apply configuration mocking if needed //Process mocking and default plugin state
if (mock) { for (const plugin of Object.keys(Plugins).filter(x => !["base", "core"].includes(x))) {
console.debug(`metrics/app > using mocked settings`) //Initialization
const {settings} = conf const {settings} = conf
//Mock token if it's undefined if (!settings.plugins[plugin])
if (!settings.token) settings.plugins[plugin] = {}
settings.token = (console.debug(`metrics/app > using mocked token`), "MOCKED_TOKEN") //Auto-enable plugin if needed
if (conf.settings["plugins.default"])
settings.plugins[plugin].enabled = settings.plugins[plugin].enabled ?? (console.debug(`metrics/app > auto-enabling ${plugin}`), true)
//Mock plugins state and tokens if they're undefined //Mock plugins state and tokens if they're undefined
for (const plugin of Object.keys(Plugins)) { if (mock) {
if (!settings.plugins[plugin]) const tokens = Object.entries(conf.metadata.plugins[plugin].inputs).filter(([key, value]) => (!/^plugin_/.test(key))&&(value.type === "token")).map(([key]) => key)
settings.plugins[plugin] = {} for (const token of tokens) {
settings.plugins[plugin].enabled = settings.plugins[plugin].enabled ?? (console.debug(`metrics/app > using mocked token enable state for ${plugin}`), true) if ((!settings.plugins[plugin][token])||(mock === "force")) {
if (["tweets", "pagespeed"].includes(plugin)) console.debug(`metrics/app > using mocked token for ${plugin}.${token}`)
settings.plugins[plugin].token = settings.plugins[plugin].token ?? (console.debug(`metrics/app > using mocked token for ${plugin}`), "MOCKED_TOKEN") settings.plugins[plugin][token] = "MOCKED_TOKEN"
if (["music"].includes(plugin)) }
settings.plugins[plugin].token = settings.plugins[plugin].token ?? (console.debug(`metrics/app > using mocked token for ${plugin}`), "MOCKED_CLIENT_ID, MOCKED_CLIENT_SECRET, MOCKED_REFRESH_TOKEN") }
} }
console.debug(util.inspect(settings, {depth:Infinity, maxStringLength:256}))
} }
if (((mock)&&(!conf.settings.token))||(mock === "force")) {
console.debug(`metrics/app > using mocked token`)
conf.settings.token = "MOCKED_TOKEN"
}
if (debug)
console.debug(util.inspect(conf.settings, {depth:Infinity, maxStringLength:256}))
//Load octokits //Load octokits
const api = {graphql:octokit.graphql.defaults({headers:{authorization: `token ${token}`}}), rest:new OctokitRest.Octokit({auth:token})} const api = {graphql:octokit.graphql.defaults({headers:{authorization: `token ${token}`}}), rest:new OctokitRest.Octokit({auth:token})}

View File

@@ -10,7 +10,7 @@
"port": 3000, "//": "Listening port", "port": 3000, "//": "Listening port",
"optimize": true, "//": "SVG optimization", "optimize": true, "//": "SVG optimization",
"debug": false, "//": "Debug logs", "debug": false, "//": "Debug logs",
"mocked": false, "//": "Use mocked data instead of live APIs", "mocked": false, "//": "Use mocked data instead of live APIs (use 'force' to use mocked token even if real token are defined)",
"repositories": 100, "//": "Number of repositories to use", "repositories": 100, "//": "Number of repositories to use",
"community": { "community": {
"templates": [], "//": "Additional community templates to setup" "templates": [], "//": "Additional community templates to setup"
@@ -19,6 +19,7 @@
"default": "classic", "//": "Default template", "default": "classic", "//": "Default template",
"enabled": [], "//": "Enabled templates (empty to enable all)" "enabled": [], "//": "Enabled templates (empty to enable all)"
}, },
"plugins.default": false, "//": "Default plugin state (advised to let 'false' unless in debug mode)",
"plugins": { "//": "Global plugin configuration", "plugins": { "//": "Global plugin configuration",
<% for (const name of Object.keys(plugins).filter(v => !["base", "core"].includes(v))) { -%> <% for (const name of Object.keys(plugins).filter(v => !["base", "core"].includes(v))) { -%>
"<%= name %>":{ "<%= name %>":{