From 6290ca575c1e050d5a1f463150809f180d540a45 Mon Sep 17 00:00:00 2001 From: linguist <22963968+lowlighter@users.noreply.github.com> Date: Wed, 30 Dec 2020 18:14:20 +0100 Subject: [PATCH] Add tests for web instance --- action/index.mjs | 17 +- index.mjs | 2 +- settings.example.json | 13 +- src/app.mjs | 50 +++- src/metrics.mjs | 11 +- src/mocks.mjs | 2 +- src/plugins/projects/index.mjs | 4 +- src/templates/common.mjs | 4 +- tests/metrics.test.js | 417 ++++++++++++++++++--------------- 9 files changed, 294 insertions(+), 226 deletions(-) diff --git a/action/index.mjs b/action/index.mjs index 8ff615d5..305c9974 100644 --- a/action/index.mjs +++ b/action/index.mjs @@ -195,26 +195,19 @@ const die = bool(core.getInput("plugins_errors_fatal")) console.log(`Plugin errors │ ${die ? "die" : "warn"}`) + //Verify svg + const verify = bool(core.getInput("verify")) + console.log(`Verify SVG │ ${verify}`) + //Build query const query = JSON.parse(core.getInput("query") || "{}") console.log(`Query additional params │ ${JSON.stringify(query)}`) q = {...query, ...q, base:false, ...base, ...config, repositories, template} //Render metrics - const rendered = await metrics({login:user, q, dflags}, {graphql, rest, plugins, conf, die}, {Plugins, Templates}) + const rendered = await metrics({login:user, q, dflags}, {graphql, rest, plugins, conf, die, verify}, {Plugins, Templates}) console.log(`Render │ complete`) - //Verify svg - const verify = bool(core.getInput("verify")) - console.log(`Verify SVG │ ${verify}`) - if (verify) { - const [libxmljs] = [await import("libxmljs")].map(m => (m && m.default) ? m.default : m) - const parsed = libxmljs.parseXml(rendered) - if (parsed.errors.length) - throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`) - console.log(`SVG valid │ yes`) - } - //Commit to repository const dryrun = bool(core.getInput("dryrun")) if (dryrun) diff --git a/index.mjs b/index.mjs index 5ab8c4fb..4a3d4f60 100644 --- a/index.mjs +++ b/index.mjs @@ -2,4 +2,4 @@ import app from "./src/app.mjs" //Start app - await app() \ No newline at end of file + await app({mock:process.env.USE_MOCKED_DATA}) \ No newline at end of file diff --git a/settings.example.json b/settings.example.json index bc42a939..9a39682c 100644 --- a/settings.example.json +++ b/settings.example.json @@ -1,4 +1,7 @@ { + "//":"This is an example of configuration file for web instance", + "//":"It is not needed when using metrics as GitHub action", + "token":"MY GITHUB API TOKEN", "//":"Your own GitHub API token (required)", "restricted":[], "//":"List of authorized users, leave empty for unrestricted", "cached":3600000, "//":"Cached time for generated images, 0 to disable", @@ -8,15 +11,13 @@ "optimize":true, "//":"Optimize SVG image", "debug":false, "//":"Debug mode", "repositories":100, "//":"Number of repositories to use to compute metrics", - "templates":{ "//":"Template configuration", "default":"classic", "//":"Default template", "enabled":[], "//":"Enabled templates, leave empty to enable all templates" }, - "plugins":{ "//":"Additional plugins (optional)", "pagespeed":{ "//":"Pagespeed plugin", - "enabled":true, "//":"Enable or disable PageSpeed metrics", + "enabled":false, "//":"Enable or disable PageSpeed metrics", "token":null, "//":"Pagespeed token (optional)" }, "traffic":{ "//":"Traffic plugin (GitHub API token must be RW for this to work)", @@ -30,10 +31,10 @@ "from":200, "//":"Number of activity events to base habits on (up to 1000)" }, "languages":{ "//":"Languages plugin", - "enabled":true, "//":"Enable or disable most used languages metrics" + "enabled":false, "//":"Enable or disable most used languages metrics" }, "followup":{ "//":"Follow-up plugin", - "enabled":true, "//":"Enable or disable owned repositories issues and pull requests metrics" + "enabled":false, "//":"Enable or disable owned repositories issues and pull requests metrics" }, "music":{ "//":"Music plugin", "enabled":false, "//":"Enable or disable music recently played / random track from playlist", @@ -55,7 +56,7 @@ "enabled":false, "//":"Enable or disable personal projects display" }, "tweets":{ "//":"Tweets plugin", - "enabled":true, "//":"Enable or disable recent tweets display", + "enabled":false, "//":"Enable or disable recent tweets display", "token":null, "//":"Twitter token (required when enabled)" } } diff --git a/src/app.mjs b/src/app.mjs index a749e22c..79286f48 100644 --- a/src/app.mjs +++ b/src/app.mjs @@ -5,20 +5,44 @@ import cache from "memory-cache" import ratelimit from "express-rate-limit" import compression from "compression" + import util from "util" import setup from "./setup.mjs" import metrics from "./metrics.mjs" - import util from "util" + import mocks from "./mocks.mjs" /** App */ - export default async function () { + export default async function ({mock = false} = {}) { //Load configuration settings const {conf, Plugins, Templates} = await setup() const {token, maxusers = 0, restricted = [], debug = false, cached = 30*60*1000, port = 3000, ratelimiter = null, plugins = null} = conf.settings + //Apply configuration mocking if needed + if (mock) { + console.debug(`metrics/app > using mocked settings`) + const {settings} = conf + //Mock token if it's undefined + if (!settings.token) + settings.token = (console.debug(`metrics/app > using mocked token`), "MOCKED_TOKEN") + //Mock plugins state and tokens if they're undefined + for (const plugin of Object.keys(Plugins)) { + if (!settings.plugins[plugin]) + settings.plugins[plugin] = {} + settings.plugins[plugin].enabled = settings.plugins[plugin].enabled ?? (console.debug(`metrics/app > using mocked token enable state for ${plugin}`), true) + if (["tweets", "pagespeed"].includes(plugin)) + settings.plugins[plugin].token = settings.plugins[plugin].token ?? (console.debug(`metrics/app > using mocked token for ${plugin}`), "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})) + } + //Load octokits - const graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}}) - const rest = new OctokitRest.Octokit({auth:token}) + const api = {graphql:octokit.graphql.defaults({headers:{authorization: `token ${token}`}}), rest:new OctokitRest.Octokit({auth:token})} + //Apply mocking if needed + if (mock) + Object.assign(api, await mocks(api)) + const {graphql, rest} = api //Setup server const app = express() @@ -108,7 +132,8 @@ try { //Render console.debug(`metrics/app/${login} > ${util.inspect(req.query, {depth:Infinity, maxStringLength:256})}`) - const rendered = await metrics({login, q:parse(req.query)}, {graphql, rest, plugins, conf}, {Plugins, Templates}) + const q = parse(req.query) + const rendered = await metrics({login, q}, {graphql, rest, plugins, conf, die:q["plugins.errors.fatal"] ?? false, verify:q["verify"] ?? false}, {Plugins, Templates}) //Cache if ((!debug)&&(cached)&&(login !== "placeholder")) cache.put(login, rendered, cached) @@ -136,13 +161,14 @@ //Listen app.listen(port, () => console.log([ - `Listening on port | ${port}`, - `Debug mode | ${debug}`, - `Restricted to users | ${restricted.size ? [...restricted].join(", ") : "(unrestricted)"}`, - `Cached time | ${cached} seconds`, - `Rate limiter | ${ratelimiter ? util.inspect(ratelimiter, {depth:Infinity, maxStringLength:256}) : "(enabled)"}`, - `Max simultaneous users | ${maxusers ? `${maxusers} users` : "(unrestricted)"}`, - `Plugins enabled | ${enabled.join(", ")}` + `Listening on port │ ${port}`, + `Debug mode │ ${debug}`, + `Restricted to users │ ${restricted.size ? [...restricted].join(", ") : "(unrestricted)"}`, + `Cached time │ ${cached} seconds`, + `Rate limiter │ ${ratelimiter ? util.inspect(ratelimiter, {depth:Infinity, maxStringLength:256}) : "(enabled)"}`, + `Max simultaneous users │ ${maxusers ? `${maxusers} users` : "(unrestricted)"}`, + `Plugins enabled │ ${enabled.join(", ")}`, + `Server ready !` ].join("\n"))) } diff --git a/src/metrics.mjs b/src/metrics.mjs index e845bf4d..3d3adfd1 100644 --- a/src/metrics.mjs +++ b/src/metrics.mjs @@ -12,7 +12,7 @@ import util from "util" //Setup - export default async function metrics({login, q, dflags = []}, {graphql, rest, plugins, conf, die = false}, {Plugins, Templates}) { + export default async function metrics({login, q, dflags = []}, {graphql, rest, plugins, conf, die = false, verify = false}, {Plugins, Templates}) { //Compute rendering try { @@ -92,6 +92,15 @@ rendered = optimized } + //Verify svg + if (verify) { + console.debug(`metrics/compute/${login} > verify SVG`) + const libxmljs = (await import("libxmljs")).default + const parsed = libxmljs.parseXml(rendered) + if (parsed.errors.length) + throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`) + } + //Result console.debug(`metrics/compute/${login} > success`) return rendered diff --git a/src/mocks.mjs b/src/mocks.mjs index 37efc261..b69f815e 100644 --- a/src/mocks.mjs +++ b/src/mocks.mjs @@ -507,7 +507,7 @@ axios.post = new Proxy(unmocked.post, { apply:function(target, that, args) { //Arguments - const [url, body, options] = args + const [url, body] = args //Spotify api if (/accounts.spotify.com.api.token/.test(url)) { //Access token generator diff --git a/src/plugins/projects/index.mjs b/src/plugins/projects/index.mjs index 67e3b247..b70d1aa2 100644 --- a/src/plugins/projects/index.mjs +++ b/src/plugins/projects/index.mjs @@ -33,13 +33,11 @@ for (const project of projects.nodes) { //Format date const time = (Date.now()-new Date(project.updatedAt).getTime())/(24*60*60*1000) - let updated + let updated = new Date(project.updatedAt).toDateString().substring(4) if (time < 1) updated = "less than 1 day ago" else if (time < 30) updated = `${Math.floor(time)} day${time >= 2 ? "s" : ""} ago` - else - updated = new Date(project.updatedAt).toDateString().substring(4) //Format progress const {enabled, todoCount:todo, inProgressCount:doing, doneCount:done} = project.progress //Append diff --git a/src/templates/common.mjs b/src/templates/common.mjs index c429d56c..24cd6c56 100644 --- a/src/templates/common.mjs +++ b/src/templates/common.mjs @@ -67,8 +67,8 @@ //Compute registration date const diff = (Date.now()-(new Date(data.user.createdAt)).getTime())/(365*24*60*60*1000) const years = Math.floor(diff) - const months = Math.ceil((diff-years)*12) - computed.registration = years ? `${years} year${s(years)} ago` : `${months} month${s(months)} ago` + const months = Math.floor((diff-years)*12) + computed.registration = years ? `${years} year${s(years)} ago` : months ? `${months} month${s(months)} ago` : `${Math.ceil(diff*365)} day${s(Math.ceil(diff*365))} ago` computed.cakeday = [new Date(), new Date(data.user.createdAt)].map(date => date.toISOString().match(/(?\d{2}-\d{2})(?=T)/)?.groups?.mmdd).every((v, _, a) => v === a[0]) //Compute calendar diff --git a/tests/metrics.test.js b/tests/metrics.test.js index c7981144..82404e2b 100644 --- a/tests/metrics.test.js +++ b/tests/metrics.test.js @@ -1,14 +1,20 @@ +/** + * @jest-environment node + */ + //Imports const processes = require("child_process") const yaml = require("js-yaml") const fs = require("fs") const path = require("path") + const url = require("url") + const axios = require("axios") //Github action const action = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "../action.yml"), "utf8")) action.defaults = Object.fromEntries(Object.entries(action.inputs).map(([key, {default:value}]) => [key, /^(yes|no)$/.test(value) ? value === "yes" : value])) action.input = vars => Object.fromEntries([...Object.entries(action.defaults), ...Object.entries(vars)].map(([key, value]) => [`INPUT_${key.toLocaleUpperCase()}`, value])) - action.run = async (vars) => await new Promise((solve, reject) => { + action.run = async (vars) => await new Promise((solve, reject) => { let [stdout, stderr] = ["", ""] const env = {...process.env, ...action.input(vars), GITHUB_REPOSITORY:"lowlighter/metrics"} const child = processes.spawn("node", ["action/index.mjs"], {env}) @@ -22,191 +28,226 @@ }) }) +//Web instance + const web = {} + web.run = async (vars) => (await axios(`http://localhost:3000/lowlighter?${new url.URLSearchParams(Object.fromEntries(Object.entries(vars).map(([key, value]) => [key.replace(/^plugin_/, "").replace(/_/g, "."), value])))}`)).status === 200 + beforeAll(async () => await new Promise((solve, reject) => { + let stdout = "" + web.instance = processes.spawn("node", ["index.mjs"], {env:{...process.env, USE_MOCKED_DATA:true}}) + web.instance.stdout.on("data", data => (stdout += data, /Server ready !/.test(stdout) ? solve() : null)) + web.instance.stderr.on("data", data => console.error(`${data}`)) + })) + afterAll(async () => await web.instance.kill()) + +//Test cases + const tests = [ + ["Base (header)", { + base:"header" + }], + ["Base (activity", { + base:"activity" + }], + ["Base (community)", { + base:"community" + }], + ["Base (repositories)", { + base:"repositories" + }], + ["Base (metadata)", { + base:"metadata" + }], + ["Base (complete)", { + base:"header, activity, community, repositories, metadata" + }], + ["PageSpeed plugin (default)", { + plugin_pagespeed:true, + }, {skip:["repository"]}], + ["PageSpeed plugin (detailed)", { + plugin_pagespeed:true, + plugin_pagespeed_detailed:true, + }, {skip:["repository"]}], + ["PageSpeed plugin (screenshot)", { + plugin_pagespeed:true, + plugin_pagespeed_screenshot:true, + }, {skip:["repository"]}], + ["PageSpeed plugin (complete)", { + plugin_pagespeed:true, + plugin_pagespeed_detailed:true, + plugin_pagespeed_screenshot:true, + }, {skip:["repository"]}], + ["Isocalendar plugin (default)", { + plugin_isocalendar: true, + }, {skip:["terminal", "repository"]}], + ["Isocalendar plugin (half-year)", { + plugin_isocalendar: true, + plugin_isocalendar_duration: "half-year", + }, {skip:["terminal", "repository"]}], + ["Isocalendar plugin (full-year)", { + plugin_isocalendar: true, + plugin_isocalendar_duration: "full-year", + }, {skip:["terminal", "repository"]}], + ["Music plugin (playlist - apple)", { + plugin_music:true, + plugin_music_playlist:"https://embed.music.apple.com/fr/playlist/usr-share/pl.u-V9D7m8Etjmjd0D", + }, {skip:["terminal", "repository"]}], + ["Music plugin (playlist - spotify)", { + plugin_music:true, + plugin_music_playlist:"https://open.spotify.com/embed/playlist/3nfA87oeJw4LFVcUDjRcqi", + }, {skip:["terminal", "repository"]}], + ["Music plugin (recent - spotify)", { + plugin_music:true, + plugin_music_provider: "spotify", + }, {skip:["terminal", "repository"]}], + ["Language plugin (default)", { + plugin_languages:true, + }, {skip:["repository"]}], + ["Language plugin (ignored languages)", { + plugin_languages:true, + plugin_languages_ignored:"html, css, dockerfile", + }, {skip:["repository"]}], + ["Language plugin (skipped repositories)", { + plugin_languages:true, + plugin_languages_skipped:"metrics", + }, {skip:["repository"]}], + ["Language plugin (complete)", { + plugin_languages:true, + plugin_languages_ignored:"html, css, dockerfile", + plugin_languages_skipped:"metrics", + }, {skip:["repository"]}], + ["Follow-up plugin (default)", { + plugin_followup:true, + }], + ["Topics plugin (default)", { + plugin_topics:true, + }, {skip:["terminal", "repository"]}], + ["Topics plugin (starred - starred sort)", { + plugin_topics:true, + plugin_topics_mode:"starred", + plugin_topics_sort:"starred", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (starred - activity sort)", { + plugin_topics:true, + plugin_topics_mode:"starred", + plugin_topics_sort:"activity", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (starred - stars sort)", { + plugin_topics:true, + plugin_topics_mode:"starred", + plugin_topics_sort:"stars", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (starred - random sort)", { + plugin_topics:true, + plugin_topics_mode:"starred", + plugin_topics_sort:"random", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (mastered - starred sort)", { + plugin_topics:true, + plugin_topics_mode:"mastered", + plugin_topics_sort:"starred", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (mastered - activity sort)", { + plugin_topics:true, + plugin_topics_mode:"mastered", + plugin_topics_sort:"activity", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (mastered - stars sort)", { + plugin_topics:true, + plugin_topics_mode:"mastered", + plugin_topics_sort:"stars", + }, {skip:["terminal", "repository"]}], + ["Topics plugin (mastered - random sort)", { + plugin_topics:true, + plugin_topics_mode:"mastered", + plugin_topics_sort:"random", + }, {skip:["terminal", "repository"]}], + ["Projects plugin (default)", { + plugin_projects:true, + }, {skip:["terminal"]}], + ["Projects plugin (repositories)", { + plugin_projects:true, + plugin_projects_repositories:"lowlighter/metrics/projects/1", + plugin_projects_limit:0, + }, {skip:["terminal"]}], + ["Lines plugin (default)", { + base:"repositories", + plugin_lines:true, + }], + ["Traffic plugin (default)", { + base:"repositories", + plugin_traffic:true, + }], + ["Tweets plugin (default)", { + plugin_tweets:true, + }, {skip:["terminal", "repository"]}], + ["Posts plugin (dev.to)", { + user:"lowlighter", + plugin_posts:true, + plugin_posts_source:"dev.to", + }, {skip:["terminal", "repository"]}], + ["Habits plugin (default)", { + plugin_habits:true, + plugin_habits_from:5, + }, {skip:["terminal", "repository"]}], + ["Habits plugin (charts)", { + plugin_habits:true, + plugin_habits_from:5, + plugin_habits_charts:true, + }, {skip:["terminal", "repository"]}], + ["Habits plugin (facts)", { + plugin_habits:true, + plugin_habits_from:5, + plugin_habits_facts:true, + }, {skip:["terminal", "repository"]}], + ["Habits plugin (complete)", { + plugin_habits:true, + plugin_habits_from:5, + plugin_habits_charts:true, + plugin_habits_charts:true, + }, {skip:["terminal", "repository"]}], + ["Gists plugin (default)", { + plugin_gists:true, + }, {skip:["terminal"]}], + ] + //Tests run - describe.each([ - ["classic", {}], - ["terminal", {}], - ["repository", {repo:"metrics"}], - ])("Template : %s", (template, query) => { - for (const [name, input, {skip = []} = {}] of [ - ["Base (header)", { - base:"header" - }], - ["Base (activity", { - base:"activity" - }], - ["Base (community)", { - base:"community" - }], - ["Base (repositories)", { - base:"repositories" - }], - ["Base (metadata)", { - base:"metadata" - }], - ["Base (complete)", { - base:"header, activity, community, repositories, metadata" - }], - ["PageSpeed plugin (default)", { - plugin_pagespeed:true, - }, {skip:["repository"]}], - ["PageSpeed plugin (detailed)", { - plugin_pagespeed:true, - plugin_pagespeed_detailed:true, - }, {skip:["repository"]}], - ["PageSpeed plugin (screenshot)", { - plugin_pagespeed:true, - plugin_pagespeed_screenshot:true, - }, {skip:["repository"]}], - ["PageSpeed plugin (complete)", { - plugin_pagespeed:true, - plugin_pagespeed_detailed:true, - plugin_pagespeed_screenshot:true, - }, {skip:["repository"]}], - ["Isocalendar plugin (default)", { - plugin_isocalendar: true, - }, {skip:["terminal", "repository"]}], - ["Isocalendar plugin (half-year)", { - plugin_isocalendar: true, - plugin_isocalendar_duration: "half-year", - }, {skip:["terminal", "repository"]}], - ["Isocalendar plugin (full-year)", { - plugin_isocalendar: true, - plugin_isocalendar_duration: "full-year", - }, {skip:["terminal", "repository"]}], - ["Music plugin (playlist - apple)", { - plugin_music:true, - plugin_music_playlist:"https://embed.music.apple.com/fr/playlist/usr-share/pl.u-V9D7m8Etjmjd0D", - }, {skip:["terminal", "repository"]}], - ["Music plugin (playlist - spotify)", { - plugin_music:true, - plugin_music_playlist:"https://open.spotify.com/embed/playlist/3nfA87oeJw4LFVcUDjRcqi", - }, {skip:["terminal", "repository"]}], - ["Music plugin (recent - spotify)", { - plugin_music:true, - plugin_music_provider: "spotify", - }, {skip:["terminal", "repository"]}], - ["Language plugin (default)", { - plugin_languages:true, - }, {skip:["repository"]}], - ["Language plugin (ignored languages)", { - plugin_languages:true, - plugin_languages_ignored:"html, css, dockerfile", - }, {skip:["repository"]}], - ["Language plugin (skipped repositories)", { - plugin_languages:true, - plugin_languages_skipped:"metrics", - }, {skip:["repository"]}], - ["Language plugin (complete)", { - plugin_languages:true, - plugin_languages_ignored:"html, css, dockerfile", - plugin_languages_skipped:"metrics", - }, {skip:["repository"]}], - ["Follow-up plugin (default)", { - plugin_followup:true, - }], - ["Topics plugin (default)", { - plugin_topics:true, - }, {skip:["terminal", "repository"]}], - ["Topics plugin (starred - starred sort)", { - plugin_topics:true, - plugin_topics_mode:"starred", - plugin_topics_sort:"starred", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (starred - activity sort)", { - plugin_topics:true, - plugin_topics_mode:"starred", - plugin_topics_sort:"activity", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (starred - stars sort)", { - plugin_topics:true, - plugin_topics_mode:"starred", - plugin_topics_sort:"stars", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (starred - random sort)", { - plugin_topics:true, - plugin_topics_mode:"starred", - plugin_topics_sort:"random", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (mastered - starred sort)", { - plugin_topics:true, - plugin_topics_mode:"mastered", - plugin_topics_sort:"starred", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (mastered - activity sort)", { - plugin_topics:true, - plugin_topics_mode:"mastered", - plugin_topics_sort:"activity", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (mastered - stars sort)", { - plugin_topics:true, - plugin_topics_mode:"mastered", - plugin_topics_sort:"stars", - }, {skip:["terminal", "repository"]}], - ["Topics plugin (mastered - random sort)", { - plugin_topics:true, - plugin_topics_mode:"mastered", - plugin_topics_sort:"random", - }, {skip:["terminal", "repository"]}], - ["Projects plugin (default)", { - plugin_projects:true, - }, {skip:["terminal"]}], - ["Projects plugin (repositories)", { - plugin_projects:true, - plugin_projects_repositories:"lowlighter/metrics/projects/1", - plugin_projects_limit:0, - }, {skip:["terminal"]}], - ["Lines plugin (default)", { - base:"repositories", - plugin_lines:true, - }], - ["Traffic plugin (default)", { - base:"repositories", - plugin_traffic:true, - }], - ["Tweets plugin (default)", { - plugin_tweets:true, - }, {skip:["terminal", "repository"]}], - ["Posts plugin (dev.to)", { - user:"lowlighter", - plugin_posts:true, - plugin_posts_source:"dev.to", - }, {skip:["terminal", "repository"]}], - ["Habits plugin (default)", { - plugin_habits:true, - plugin_habits_from:5, - }, {skip:["terminal", "repository"]}], - ["Habits plugin (charts)", { - plugin_habits:true, - plugin_habits_from:5, - plugin_habits_charts:true, - }, {skip:["terminal", "repository"]}], - ["Habits plugin (facts)", { - plugin_habits:true, - plugin_habits_from:5, - plugin_habits_facts:true, - }, {skip:["terminal", "repository"]}], - ["Habits plugin (complete)", { - plugin_habits:true, - plugin_habits_from:5, - plugin_habits_charts:true, - plugin_habits_charts:true, - }, {skip:["terminal", "repository"]}], - ["Gists plugin (default)", { - plugin_gists:true, - }, {skip:["terminal"]}], - ]) - if (skip.includes(template)) - test.skip(name, () => null) - else - test(name, async () => expect(await action.run({ - token:"MOCKED_TOKEN", - plugin_pagespeed_token:"MOCKED_TOKEN", - plugin_tweets_token:"MOCKED_TOKEN", - plugin_music_token:"MOCKED_CLIENT_ID, MOCKED_CLIENT_SECRET, MOCKED_REFRESH_TOKEN", - template, base:"", query:JSON.stringify(query), - config_timezone:"Europe/Paris", - plugins_errors_fatal:true, dryrun:true, use_mocked_data:true, verify:true, - ...input - })).toBe(true), 60*1e3) - }) + describe("GitHub Action", () => + describe.skip.each([ + ["classic", {}], + ["terminal", {}], + ["repository", {repo:"metrics"}], + ])("Template : %s", (template, query) => { + for (const [name, input, {skip = []} = {}] of tests) + if (skip.includes(template)) + test.skip(name, () => null) + else + test(name, async () => expect(await action.run({ + token:"MOCKED_TOKEN", + plugin_pagespeed_token:"MOCKED_TOKEN", + plugin_tweets_token:"MOCKED_TOKEN", + plugin_music_token:"MOCKED_CLIENT_ID, MOCKED_CLIENT_SECRET, MOCKED_REFRESH_TOKEN", + template, base:"", query:JSON.stringify(query), + config_timezone:"Europe/Paris", + plugins_errors_fatal:true, dryrun:true, use_mocked_data:true, verify:true, + ...input + })).toBe(true), 60*1e3) + }) + ) + + describe("Web instance", () => + describe.each([ + // ["classic", {}], + ["terminal", {}], + // ["repository", {repo:"metrics"}], + ])("Template : %s", (template, query) => { + for (const [name, input, {skip = []} = {}] of tests) + if (skip.includes(template)) + test.skip(name, () => null) + else + test(name, async () => expect(await web.run({ + template, base:0, ...query, + config_timezone:"Europe/Paris", + plugins_errors_fatal:true, verify:true, + ...input + })).toBe(true), 60*1e3) + }) + ) \ No newline at end of file