1899 validate exercises by fetching them and checking the JSON#147
1899 validate exercises by fetching them and checking the JSON#147philschatz wants to merge 22 commits into
Conversation
4f16a5e to
1547176
Compare
1547176 to
4d0d6b7
Compare
TylerZeroMaster
left a comment
There was a problem hiding this comment.
Those are some pretty major changes to validation. It's definitely more explicit. It also helps cut down on repetitive .filter(...).map(...) operations.
I am not very well versed in how exercises work; however, I read through the Slack thread and the cnx-epub PR you linked and, as far as I can tell, you covered everything.
|
The CLI found several errors which would show up as errors to CM's when they try to commit any of these repos:
These errors seem to be correct. Just search for Also, we could make them Warnings which would notify CMs without preventing them from committing |
|
I will make a card for the CMs to address the above issues. |
df6926f to
649ec14
Compare
|
I found a way to concisely read/write a cache of the exercise JSON. For now, I'll write them to a temp directory inside gitpod, so they will disappear when the workspace disappears. Once that works for a while we can discuss committing the exercises to git. To be programming-language-agnostic, the filenames in the cache directory are As a proof of concept, this is a proxy server that reads/writes to the cache directory using the format that the Language Server will read/write. 'use strict';
// Usage:
// PORT=3001 TARGET_URL=https://exercises.openstax.org CACHE_DIR=./exercise-cache/ node ./proxy.js
const fs = require('fs');
const path = require('path');
const restify = require('restify')
const bent = require('bent');
const server = restify.createServer();
function getEnv(name) {
const v = process.env[name]
if (v) return v
throw new Error(`Missing required environment variable ${name}`)
}
const port = Number.parseInt(getEnv('PORT'))
const target = getEnv('TARGET_URL')
const cacheDirName = getEnv('CACHE_DIR')
const enableNetwork = !!process.env['ENABLE_NETWORK']
// Always GET json and error if the response is anything except 200
const rootGet = bent(target, 'GET', 'json', 200)
const cachePath = path.resolve(cacheDirName)
function toFilename(url) {
return path.join(cachePath, `${encodeURIComponent(url)}.json`)
}
function readCache(filename) {
const cacheItem = JSON.parse(fs.readFileSync(filename, 'utf-8'))
if (cacheItem.version !== 1) throw new Error('Unsupported storage format. Expected version 1')
return cacheItem.body
}
async function updateCache(url) {
if (!enableNetwork) throw new Error('Network requests are disabled. To enable them set the environment variable ENABLE_NETWORK=1')
console.log('Fetching', target, url)
const jsonBody = await rootGet(url)
const cacheItem = {
version: 1,
body: jsonBody,
// etag:
}
fs.writeFileSync(toFilename(url), JSON.stringify(cacheItem, null, 2))
return jsonBody
}
function asyncWrapper(fn) {
return (req, res, next) => {
return Promise.resolve(fn(req))
.then((result) => res.send(result))
.catch((err) => next(err))
}
}
server.get('/.*', asyncWrapper(async (req) => {
const url = req.url
const filename = toFilename(url)
let jsonBody
if (fs.existsSync(filename)) {
jsonBody = readCache(filename)
// Async update the cache
if (enableNetwork) void updateCache(url)
} else {
jsonBody = await updateCache(url)
}
return jsonBody
}))
server.listen(port, function() {
console.log(`Proxy server started up on port ${port}`);
}); |
because code coverage was fixed
45596cc to
87ecc9c
Compare
So pushing a book is not affected
|
(copied from https://github.com/openstax/ce/issues/1899) Closing for now but should reopen when work resumes.
|
|
Added some fixes: @04ba826e |
|
Where does this stand now? |
A step in the baking process (cnx-epub) fetches the exercise and fails if certain tags that are on the exercise do not correspond to content in the book.
Problem
An exercise was added to a new module. The exercise had an element in the book that was necessary to answer the question and the rules for looking up the element are wonky:
context-cnxmod:<UUID>tags on the exercise then look up thecontext-cnxfeature:<elementID>on the page where the exercise is linked (<-- this case silently failed)context-cnxmod:<UUID>tags then loop through them and pick the first UUID that is in the bookSolution
TODO
MementosExtension-specific Configuration Directory to cache the GET requests for the exercise JSONSlack Context