From 1519b65ecc174231f976231b78ed8cc2c35a251a Mon Sep 17 00:00:00 2001 From: driatic Date: Wed, 28 Jun 2023 11:43:55 +0200 Subject: [PATCH 1/5] feat: rewrite generate test --- __test-utils__/create-migration.js | 6 ++-- __test-utils__/log.js | 4 +-- __tests__/generate.test.js | 16 +++++---- __tests__/list.test.js | 22 ++++++------- __tests__/migrate.test.js | 11 +++---- bin/commands/generate.js | 33 +++++++++++-------- bin/commands/rollback.js | 2 +- jest.setupFiles.js | 9 +++-- jest.setupFilesAfterEnv.js | 3 +- mocks/contentful/baseContentfulHandler.js | 4 +-- .../list/noAppliedMigrationsHandler.js | 4 +-- .../list/oneAppliedMigrationsHandler.js | 4 +-- traffic/interceptor.js | 2 +- 13 files changed, 64 insertions(+), 56 deletions(-) diff --git a/__test-utils__/create-migration.js b/__test-utils__/create-migration.js index 9c569d6..bd4a596 100644 --- a/__test-utils__/create-migration.js +++ b/__test-utils__/create-migration.js @@ -25,9 +25,9 @@ module.exports.createSimpleMigrationFile = () => { fs.writeFileSync(migrationPath, content, (err) => { if (err) { - console.error(err); + console.error(err) return; } - console.log('File created successfully!'); - }); + console.log('File created successfully!') + }) } \ No newline at end of file diff --git a/__test-utils__/log.js b/__test-utils__/log.js index 17f991c..603e4b1 100644 --- a/__test-utils__/log.js +++ b/__test-utils__/log.js @@ -3,8 +3,8 @@ module.exports.extractLogLinesFromConsole = () => { const originalLog = console.log; const allLogMessages = []; console.log = (...args) => { - allLogMessages.push(args.toString()); - originalLog(...args); //print to default console + allLogMessages.push(args.toString()) + originalLog(...args) //print to default console } return allLogMessages; } \ No newline at end of file diff --git a/__tests__/generate.test.js b/__tests__/generate.test.js index 0be8742..9e5f0fa 100644 --- a/__tests__/generate.test.js +++ b/__tests__/generate.test.js @@ -1,18 +1,22 @@ -const { execaNode } = require("execa"); const fs = require('fs') const { join } = require('path') +const {handler: generateCommand} = require("../bin/commands/generate") +const {extractLogLinesFromConsole} = require("../__test-utils__/log") +const {readdirSync} = require("fs") -//todo: rewrite to match refactored other tests? describe('generate', () => { it('should create a new migration file', async () => { + const stdout = extractLogLinesFromConsole() const migrationName = 'test-migration' - const { stdout } = await execaNode('./bin/cmp.js', ['generate', migrationName]) + await generateCommand({name: migrationName}) - const migrationFileName = stdout.split(' ').find((m) => m.indexOf('js') > -1) - const migrationFile = fs.readFileSync(`${process.env.MIGRATIONS_DIR}/${migrationFileName}`, 'utf-8') + let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR) + expect(numberOfMigrationsInMigrationsDir.length).toBe(1) + const migrationFileName = stdout[0].split(' ').find((m) => m.indexOf('js') > -1) + const migrationFilePath = `${process.env.MIGRATIONS_DIR}/${migrationFileName}` + const migrationFile = fs.readFileSync(migrationFilePath, 'utf-8') const template = fs.readFileSync(join(__dirname, '..', 'templates', 'migration.mustache'), 'utf8') - expect(migrationFile).toEqual(template) }) }) diff --git a/__tests__/list.test.js b/__tests__/list.test.js index b224c30..3c2dfcc 100644 --- a/__tests__/list.test.js +++ b/__tests__/list.test.js @@ -1,10 +1,10 @@ -const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler"); -const {handler: listCommand} = require("../bin/commands/list"); -const {extractLogLinesFromConsole} = require("../__test-utils__/log"); -const {listOneMigrationAppliedHandler} = require("../mocks/contentful/handlers/list/oneAppliedMigrationsHandler"); -const {listNoAppliedMigrationHandler} = require("../mocks/contentful/handlers/list/noAppliedMigrationsHandler"); -const {createSimpleMigrationFile} = require("../__test-utils__/create-migration"); -const {readdirSync} = require("fs"); +const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler") +const {handler: listCommand} = require("../bin/commands/list") +const {extractLogLinesFromConsole} = require("../__test-utils__/log") +const {listOneMigrationAppliedHandler} = require("../mocks/contentful/handlers/list/oneAppliedMigrationsHandler") +const {listNoAppliedMigrationHandler} = require("../mocks/contentful/handlers/list/noAppliedMigrationsHandler") +const {createSimpleMigrationFile} = require("../__test-utils__/create-migration") +const {readdirSync} = require("fs") describe('list', () => { it('should log that no migrations are applied', async () => { @@ -12,11 +12,11 @@ describe('list', () => { let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length; expect(numberOfMigrationsInMigrationsDir).toBe(0) - const stdout = extractLogLinesFromConsole(); + const stdout = extractLogLinesFromConsole() await listCommand() expect(stdout).toContain("Found no applied migrations") closeMockedContentfulApi() - }); + }) it('should log that migrations are applied', async () => { setupMockedContentfulApi(listOneMigrationAppliedHandler) @@ -25,11 +25,11 @@ describe('list', () => { let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length; expect(numberOfMigrationsInMigrationsDir).toBe(1) - const stdout = extractLogLinesFromConsole(); + const stdout = extractLogLinesFromConsole() await listCommand() expect(stdout).toContain("Applied migrations:") expect(stdout).toContain("20230609122547608 - new-migration") closeMockedContentfulApi() - }); + }) }) diff --git a/__tests__/migrate.test.js b/__tests__/migrate.test.js index ea4329d..74c6bae 100644 --- a/__tests__/migrate.test.js +++ b/__tests__/migrate.test.js @@ -1,14 +1,13 @@ const { execaNode -} = require("execa"); -const {handler: migrateCommand} = require("../bin/commands/migrate"); -const {extractLogLinesFromConsole} = require("../__test-utils__/log"); -const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler"); +} = require("execa") +const {handler: migrateCommand} = require("../bin/commands/migrate") +const {extractLogLinesFromConsole} = require("../__test-utils__/log") +const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler") describe('migrate', () => { - it('should demand user to use "--force" flag if running against master space', async () => { setupMockedContentfulApi() - const stdout = extractLogLinesFromConsole(); + const stdout = extractLogLinesFromConsole() await migrateCommand(false) expect(stdout).toContain("Executing migrations against master requires the --force flag.") closeMockedContentfulApi() diff --git a/bin/commands/generate.js b/bin/commands/generate.js index befae88..7c9146e 100755 --- a/bin/commands/generate.js +++ b/bin/commands/generate.js @@ -1,10 +1,9 @@ #! /usr/bin/env node - const fs = require('fs') -const { join } = require('path') +const {join} = require('path') const Mustache = require('mustache') -const { utcTimestampMs } = require('../../lib/date') -const { camelToKebabCase } = require('../../lib/string') +const {utcTimestampMs} = require('../../lib/date') +const {camelToKebabCase} = require('../../lib/string') const env = require('../../lib/env') const log = require('../../lib/log') @@ -19,15 +18,14 @@ exports.builder = (yargs) => { }) } -exports.handler = ({ name }) => { +exports.handler = async ({name}) => { try { const templatePath = fs.readFileSync(join(__dirname, '..', '..', 'templates', 'migration.mustache'), 'utf8') - const migrationContents = Mustache.render(templatePath) const migrationFileName = `${utcTimestampMs()}-${camelToKebabCase(name)}.js` const migrationsDir = env('MIGRATIONS_DIR') - fs.mkdir(migrationsDir, { recursive: true }, (err) => { + fs.mkdir(migrationsDir, {recursive: true}, (err) => { if (err) { throw err } @@ -35,14 +33,23 @@ exports.handler = ({ name }) => { const migrationPath = join(migrationsDir, migrationFileName) - fs.writeFile(migrationPath, migrationContents, { flag: 'w' }, (err) => { - if (err) { - throw err - } - log.success(`Migration file ${migrationFileName} created`) - }) + await writeFileAsync(migrationPath, migrationContents) + log.success(`Migration file ${migrationFileName} created`) } catch (e) { log.error('Migration file creation failed.', e) process.exitCode = 1 } } + +//todo: move to utility if we need this elsewhere +function writeFileAsync(filePath, data) { + return new Promise((resolve, reject) => { + fs.writeFile(filePath, data, (error) => { + if (error) { + reject(error) + } else { + resolve() + } + }) + }) +} diff --git a/bin/commands/rollback.js b/bin/commands/rollback.js index 0b01247..75aa2f2 100644 --- a/bin/commands/rollback.js +++ b/bin/commands/rollback.js @@ -5,7 +5,7 @@ const { apply, list } = require('../../src/migrator') const env = require('../../lib/env') const cliSelect = require('cli-select') const spaceModule = require('../../lib/contentful-space-manager') -const log = require("../../lib/log"); +const log = require("../../lib/log") exports.command = 'rollback' diff --git a/jest.setupFiles.js b/jest.setupFiles.js index 819989a..5e2e6a4 100644 --- a/jest.setupFiles.js +++ b/jest.setupFiles.js @@ -1,6 +1,5 @@ -const dotenv = require("dotenv"); -const {setupInterceptorServer} = require("./traffic/interceptor"); -dotenv.config({ path: './.env.test' }); +const dotenv = require("dotenv") +dotenv.config({ path: './.env.test' }) //mock lib/log since encoding characters from chalk makes testing difficult jest.mock('./lib/log', () => { @@ -11,5 +10,5 @@ jest.mock('./lib/log', () => { success: (...message) => console.log(...message), error: (...message) => console.log(...message), warn: (...message) => console.log(...message), - }; -}); \ No newline at end of file + } +}) \ No newline at end of file diff --git a/jest.setupFilesAfterEnv.js b/jest.setupFilesAfterEnv.js index 8ad0f8b..c92632a 100644 --- a/jest.setupFilesAfterEnv.js +++ b/jest.setupFilesAfterEnv.js @@ -1,11 +1,10 @@ const fs = require('fs') const Path = require('path') -const dotenv = require("dotenv"); beforeAll(() => { let migrationsDir = process.env.MIGRATIONS_DIR if (!fs.existsSync(migrationsDir)){ - fs.mkdirSync(migrationsDir); + fs.mkdirSync(migrationsDir) } }) diff --git a/mocks/contentful/baseContentfulHandler.js b/mocks/contentful/baseContentfulHandler.js index 44fc867..c81fa1e 100644 --- a/mocks/contentful/baseContentfulHandler.js +++ b/mocks/contentful/baseContentfulHandler.js @@ -1,6 +1,6 @@ const {setupServer} = require('msw/node') -const log = require("../../lib/log"); -const {rest} = require("msw"); +const log = require("../../lib/log") +const {rest} = require("msw") let mockedContentfulServer = null diff --git a/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js b/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js index 2566eb2..cefef87 100644 --- a/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js +++ b/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js @@ -1,5 +1,5 @@ -const {rest} = require("msw"); -const {baseURL} = require("../../baseContentfulHandler"); +const {rest} = require("msw") +const {baseURL} = require("../../baseContentfulHandler") module.exports.listNoAppliedMigrationHandler = [ rest.get(`${baseURL}/environments/master/entries`, (req, res, ctx) => { return res( diff --git a/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js b/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js index 0ecfaa1..6918304 100644 --- a/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js +++ b/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js @@ -1,5 +1,5 @@ -const {rest} = require("msw"); -const {baseURL} = require("../../baseContentfulHandler"); +const {rest} = require("msw") +const {baseURL} = require("../../baseContentfulHandler") module.exports.listOneMigrationAppliedHandler = [ rest.get(`${baseURL}/environments/master/entries`, (req, res, ctx) => { diff --git a/traffic/interceptor.js b/traffic/interceptor.js index e7dfa83..80b0740 100644 --- a/traffic/interceptor.js +++ b/traffic/interceptor.js @@ -3,7 +3,7 @@ const {rest} = require('msw') const fs = require('fs') const path = require('path') const {setupServer} = require('msw/node') -const log = require("../lib/log"); +const log = require("../lib/log") const requests = new Map() const transactions = new Set() From 086214f29ff9b58625e40174ab52d75aafe68581 Mon Sep 17 00:00:00 2001 From: driatic Date: Tue, 11 Jul 2023 10:37:51 +0200 Subject: [PATCH 2/5] feat: improvements --- __tests__/generate.test.js | 5 +-- __tests__/rollback.test.js | 13 ++++++ bin/cmp.js | 3 ++ mocks/contentful/baseContentfulHandler.js | 13 +++--- traffic/interceptor.js | 55 +++++++++++++---------- 5 files changed, 55 insertions(+), 34 deletions(-) create mode 100644 __tests__/rollback.test.js diff --git a/__tests__/generate.test.js b/__tests__/generate.test.js index 9e5f0fa..f0b638b 100644 --- a/__tests__/generate.test.js +++ b/__tests__/generate.test.js @@ -2,7 +2,6 @@ const fs = require('fs') const { join } = require('path') const {handler: generateCommand} = require("../bin/commands/generate") const {extractLogLinesFromConsole} = require("../__test-utils__/log") -const {readdirSync} = require("fs") describe('generate', () => { it('should create a new migration file', async () => { @@ -10,8 +9,8 @@ describe('generate', () => { const migrationName = 'test-migration' await generateCommand({name: migrationName}) - let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR) - expect(numberOfMigrationsInMigrationsDir.length).toBe(1) + let numberOfMigrationsInMigrationsDir = fs.readdirSync(process.env.MIGRATIONS_DIR).length + expect(numberOfMigrationsInMigrationsDir).toBe(1) const migrationFileName = stdout[0].split(' ').find((m) => m.indexOf('js') > -1) const migrationFilePath = `${process.env.MIGRATIONS_DIR}/${migrationFileName}` diff --git a/__tests__/rollback.test.js b/__tests__/rollback.test.js new file mode 100644 index 0000000..fa471e4 --- /dev/null +++ b/__tests__/rollback.test.js @@ -0,0 +1,13 @@ +const fs = require('fs') +const { join } = require('path') +const {handler: rollbackCommand} = require("../bin/commands/rollback") +const {extractLogLinesFromConsole} = require("../__test-utils__/log") +const {handler: migrateCommand} = require("../bin/commands/migrate"); + +describe('rollback', () => { + it('should demand user to use "--force" flag if running against master space', async () => { + const stdout = extractLogLinesFromConsole() + await rollbackCommand({force: false}) + expect(stdout).toContain("Executing migrations against master requires the --force flag.") + }) +}) diff --git a/bin/cmp.js b/bin/cmp.js index 0227850..4d5b461 100755 --- a/bin/cmp.js +++ b/bin/cmp.js @@ -1,5 +1,8 @@ #!/usr/bin/env node +const {setupInterceptorServer} = require("../traffic/interceptor") +setupInterceptorServer({logUnhandledRequests: true}) + require('yargs') .usage('Contentful migration tooling.') .commandDir('commands') diff --git a/mocks/contentful/baseContentfulHandler.js b/mocks/contentful/baseContentfulHandler.js index c81fa1e..47a6ee3 100644 --- a/mocks/contentful/baseContentfulHandler.js +++ b/mocks/contentful/baseContentfulHandler.js @@ -10,15 +10,14 @@ module.exports.setupMockedContentfulApi = (handlers) => { if (handlers == null) { handlers = [] } + let totalNumberOfRequests = 0 log.info("setting up mocked contentful rest server") const server = setupServer(...spacesHandler, ...localeHandler, ...masterEnvironmentHandler, ...handlers) //log unhandled requests server.listen({ onUnhandledRequest(req) { - log.warn( - `* Found an unhandled ${req.method} request to ${req.url.href}`, - ) + log.warn(`* Found an unhandled ${req.method} request to ${req.url.href}`,) }, }) @@ -28,9 +27,9 @@ module.exports.setupMockedContentfulApi = (handlers) => { server.events.on('request:start', (request, response) => { // Record every dispatched request. - log.info( - `* intercepting ${request.method} request to ${request.url}`, - ) + log.info(`* intercepting ${request.method} request to ${request.url}`,) + totalNumberOfRequests++ + log.info('Total number of requests: ' , totalNumberOfRequests) }) mockedContentfulServer = server @@ -38,7 +37,7 @@ module.exports.setupMockedContentfulApi = (handlers) => { module.exports.closeMockedContentfulApi = () => { console.log("CLOSING MOCKED CONTENTFUL SERVER") - if(mockedContentfulServer != null ){ + if (mockedContentfulServer != null) { mockedContentfulServer.close() } } diff --git a/traffic/interceptor.js b/traffic/interceptor.js index 80b0740..813ba0b 100644 --- a/traffic/interceptor.js +++ b/traffic/interceptor.js @@ -12,42 +12,49 @@ const server = setupServer() //this utility can be used to record all network traffic. // Each request and response during app lifetime is logged to json in the traffic/output directory. //run setupInterceptorServer() in bin/cmp.js for this to work. -module.exports.setupInterceptorServer = () => { +module.exports.setupInterceptorServer = ({logUnhandledRequests, logBypassedTraffic, saveTrafficToFile}) => { log.info("setting up network traffic interceptor server") //catch requests from underlying dependencies - server.listen({ - onUnhandledRequest(req) { - log.warn( - `* Found an unhandled ${req.method} request to ${req.url.href}`, - ) - }, - }) + if(logUnhandledRequests){ + server.listen({ + onUnhandledRequest(req) { + log.warn( + `* Found an unhandled ${req.method} request to ${req.url.href}`, + ) + }, + }) + } - server.events.on('request:start', (request, response) => { - // Record every dispatched request. - log.info( - `* intercepting ${request.method} request to ${request.url}`, - ) - requests.set(request.id, request) - transactions.add([request, response]) - }) + if(logBypassedTraffic){ + server.events.on('request:start', (request, response) => { + // Record every dispatched request. + log.info( + `* intercepting ${request.method} request to ${request.url}`, + ) + requests.set(request.id, request) + transactions.add([request, response]) + }) // Since we're not providing any request handlers // to the "setupServer" call, all responses will be // bypassed (performed as-is). This will allow us to // collect the actual responses. - server.events.on('response:bypass', (response, requestId) => { - log.info( - `* receiving status ${response.status} from ${requests.get(requestId).url}`, - ) - const request = requests.get(requestId) - transactions.add([request, response]) - }) + server.events.on('response:bypass', (response, requestId) => { + log.info( + `* receiving status ${response.status} from ${requests.get(requestId).url}`, + ) + const request = requests.get(requestId) + transactions.add([request, response]) + }) + } + process.on('exit', () => { log.info("handling exit") - this.writeTrafficToFile() + if(saveTrafficToFile){ + this.writeTrafficToFile() + } }) } From 01110fa2fe3603cb9eee34af209a636074ccf4a5 Mon Sep 17 00:00:00 2001 From: driatic Date: Thu, 13 Jul 2023 09:58:15 +0200 Subject: [PATCH 3/5] feat: run prettier on all files --- __test-utils__/create-migration.js | 6 +- __test-utils__/log.js | 8 +- __tests__/generate.test.js | 6 +- __tests__/list.test.js | 25 +- __tests__/migrate.test.js | 11 +- __tests__/rollback.test.js | 10 +- bin/cmp.js | 7 +- bin/commands/generate.js | 10 +- bin/commands/rollback.js | 2 +- jest.setupFiles.js | 6 +- jest.setupFilesAfterEnv.js | 2 +- lib/env.js | 2 +- mocks/contentful/baseContentfulHandler.js | 261 ++++++------ .../list/noAppliedMigrationsHandler.js | 247 ++++++------ .../list/oneAppliedMigrationsHandler.js | 375 +++++++++--------- traffic/interceptor.js | 46 +-- 16 files changed, 498 insertions(+), 526 deletions(-) diff --git a/__test-utils__/create-migration.js b/__test-utils__/create-migration.js index bd4a596..b606adb 100644 --- a/__test-utils__/create-migration.js +++ b/__test-utils__/create-migration.js @@ -18,7 +18,7 @@ module.exports.createSimpleMigrationFile = () => { module.exports.down = (migration, context) => { migration.deleteContentType('testContentType') - }`; + }` const migrationsDir = process.env.MIGRATIONS_DIR const migrationFileName = '20230609122547608-new-migration.js' const migrationPath = join(migrationsDir, migrationFileName) @@ -26,8 +26,8 @@ module.exports.createSimpleMigrationFile = () => { fs.writeFileSync(migrationPath, content, (err) => { if (err) { console.error(err) - return; + return } console.log('File created successfully!') }) -} \ No newline at end of file +} diff --git a/__test-utils__/log.js b/__test-utils__/log.js index 603e4b1..51db462 100644 --- a/__test-utils__/log.js +++ b/__test-utils__/log.js @@ -1,10 +1,10 @@ //utility to get all console log messages in a test context module.exports.extractLogLinesFromConsole = () => { - const originalLog = console.log; - const allLogMessages = []; + const originalLog = console.log + const allLogMessages = [] console.log = (...args) => { allLogMessages.push(args.toString()) originalLog(...args) //print to default console } - return allLogMessages; -} \ No newline at end of file + return allLogMessages +} diff --git a/__tests__/generate.test.js b/__tests__/generate.test.js index f0b638b..e1e4034 100644 --- a/__tests__/generate.test.js +++ b/__tests__/generate.test.js @@ -1,13 +1,13 @@ const fs = require('fs') const { join } = require('path') -const {handler: generateCommand} = require("../bin/commands/generate") -const {extractLogLinesFromConsole} = require("../__test-utils__/log") +const { handler: generateCommand } = require('../bin/commands/generate') +const { extractLogLinesFromConsole } = require('../__test-utils__/log') describe('generate', () => { it('should create a new migration file', async () => { const stdout = extractLogLinesFromConsole() const migrationName = 'test-migration' - await generateCommand({name: migrationName}) + await generateCommand({ name: migrationName }) let numberOfMigrationsInMigrationsDir = fs.readdirSync(process.env.MIGRATIONS_DIR).length expect(numberOfMigrationsInMigrationsDir).toBe(1) diff --git a/__tests__/list.test.js b/__tests__/list.test.js index 3c2dfcc..d83751a 100644 --- a/__tests__/list.test.js +++ b/__tests__/list.test.js @@ -1,20 +1,20 @@ -const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler") -const {handler: listCommand} = require("../bin/commands/list") -const {extractLogLinesFromConsole} = require("../__test-utils__/log") -const {listOneMigrationAppliedHandler} = require("../mocks/contentful/handlers/list/oneAppliedMigrationsHandler") -const {listNoAppliedMigrationHandler} = require("../mocks/contentful/handlers/list/noAppliedMigrationsHandler") -const {createSimpleMigrationFile} = require("../__test-utils__/create-migration") -const {readdirSync} = require("fs") +const { setupMockedContentfulApi, closeMockedContentfulApi } = require('../mocks/contentful/baseContentfulHandler') +const { handler: listCommand } = require('../bin/commands/list') +const { extractLogLinesFromConsole } = require('../__test-utils__/log') +const { listOneMigrationAppliedHandler } = require('../mocks/contentful/handlers/list/oneAppliedMigrationsHandler') +const { listNoAppliedMigrationHandler } = require('../mocks/contentful/handlers/list/noAppliedMigrationsHandler') +const { createSimpleMigrationFile } = require('../__test-utils__/create-migration') +const { readdirSync } = require('fs') describe('list', () => { it('should log that no migrations are applied', async () => { setupMockedContentfulApi(listNoAppliedMigrationHandler) - let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length; + let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length expect(numberOfMigrationsInMigrationsDir).toBe(0) const stdout = extractLogLinesFromConsole() await listCommand() - expect(stdout).toContain("Found no applied migrations") + expect(stdout).toContain('Found no applied migrations') closeMockedContentfulApi() }) @@ -22,14 +22,13 @@ describe('list', () => { setupMockedContentfulApi(listOneMigrationAppliedHandler) createSimpleMigrationFile() - let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length; + let numberOfMigrationsInMigrationsDir = readdirSync(process.env.MIGRATIONS_DIR).length expect(numberOfMigrationsInMigrationsDir).toBe(1) const stdout = extractLogLinesFromConsole() await listCommand() - expect(stdout).toContain("Applied migrations:") - expect(stdout).toContain("20230609122547608 - new-migration") + expect(stdout).toContain('Applied migrations:') + expect(stdout).toContain('20230609122547608 - new-migration') closeMockedContentfulApi() }) }) - diff --git a/__tests__/migrate.test.js b/__tests__/migrate.test.js index 74c6bae..9d73dbc 100644 --- a/__tests__/migrate.test.js +++ b/__tests__/migrate.test.js @@ -1,15 +1,14 @@ -const { execaNode -} = require("execa") -const {handler: migrateCommand} = require("../bin/commands/migrate") -const {extractLogLinesFromConsole} = require("../__test-utils__/log") -const {setupMockedContentfulApi, closeMockedContentfulApi} = require("../mocks/contentful/baseContentfulHandler") +const { execaNode } = require('execa') +const { handler: migrateCommand } = require('../bin/commands/migrate') +const { extractLogLinesFromConsole } = require('../__test-utils__/log') +const { setupMockedContentfulApi, closeMockedContentfulApi } = require('../mocks/contentful/baseContentfulHandler') describe('migrate', () => { it('should demand user to use "--force" flag if running against master space', async () => { setupMockedContentfulApi() const stdout = extractLogLinesFromConsole() await migrateCommand(false) - expect(stdout).toContain("Executing migrations against master requires the --force flag.") + expect(stdout).toContain('Executing migrations against master requires the --force flag.') closeMockedContentfulApi() }) }) diff --git a/__tests__/rollback.test.js b/__tests__/rollback.test.js index fa471e4..48202b3 100644 --- a/__tests__/rollback.test.js +++ b/__tests__/rollback.test.js @@ -1,13 +1,13 @@ const fs = require('fs') const { join } = require('path') -const {handler: rollbackCommand} = require("../bin/commands/rollback") -const {extractLogLinesFromConsole} = require("../__test-utils__/log") -const {handler: migrateCommand} = require("../bin/commands/migrate"); +const { handler: rollbackCommand } = require('../bin/commands/rollback') +const { extractLogLinesFromConsole } = require('../__test-utils__/log') +const { handler: migrateCommand } = require('../bin/commands/migrate') describe('rollback', () => { it('should demand user to use "--force" flag if running against master space', async () => { const stdout = extractLogLinesFromConsole() - await rollbackCommand({force: false}) - expect(stdout).toContain("Executing migrations against master requires the --force flag.") + await rollbackCommand({ force: false }) + expect(stdout).toContain('Executing migrations against master requires the --force flag.') }) }) diff --git a/bin/cmp.js b/bin/cmp.js index 4d5b461..a4f69cc 100755 --- a/bin/cmp.js +++ b/bin/cmp.js @@ -1,11 +1,10 @@ #!/usr/bin/env node -const {setupInterceptorServer} = require("../traffic/interceptor") -setupInterceptorServer({logUnhandledRequests: true}) +const { setupInterceptorServer } = require('../traffic/interceptor') +setupInterceptorServer({ logUnhandledRequests: true }) require('yargs') .usage('Contentful migration tooling.') .commandDir('commands') .recommendCommands() - .demandCommand(1, 'Have a look at the commands above and pick one.') - .argv + .demandCommand(1, 'Have a look at the commands above and pick one.').argv diff --git a/bin/commands/generate.js b/bin/commands/generate.js index 7c9146e..793e6d9 100755 --- a/bin/commands/generate.js +++ b/bin/commands/generate.js @@ -1,9 +1,9 @@ #! /usr/bin/env node const fs = require('fs') -const {join} = require('path') +const { join } = require('path') const Mustache = require('mustache') -const {utcTimestampMs} = require('../../lib/date') -const {camelToKebabCase} = require('../../lib/string') +const { utcTimestampMs } = require('../../lib/date') +const { camelToKebabCase } = require('../../lib/string') const env = require('../../lib/env') const log = require('../../lib/log') @@ -18,14 +18,14 @@ exports.builder = (yargs) => { }) } -exports.handler = async ({name}) => { +exports.handler = async ({ name }) => { try { const templatePath = fs.readFileSync(join(__dirname, '..', '..', 'templates', 'migration.mustache'), 'utf8') const migrationContents = Mustache.render(templatePath) const migrationFileName = `${utcTimestampMs()}-${camelToKebabCase(name)}.js` const migrationsDir = env('MIGRATIONS_DIR') - fs.mkdir(migrationsDir, {recursive: true}, (err) => { + fs.mkdir(migrationsDir, { recursive: true }, (err) => { if (err) { throw err } diff --git a/bin/commands/rollback.js b/bin/commands/rollback.js index 75aa2f2..05289fd 100644 --- a/bin/commands/rollback.js +++ b/bin/commands/rollback.js @@ -5,7 +5,7 @@ const { apply, list } = require('../../src/migrator') const env = require('../../lib/env') const cliSelect = require('cli-select') const spaceModule = require('../../lib/contentful-space-manager') -const log = require("../../lib/log") +const log = require('../../lib/log') exports.command = 'rollback' diff --git a/jest.setupFiles.js b/jest.setupFiles.js index 5e2e6a4..9485304 100644 --- a/jest.setupFiles.js +++ b/jest.setupFiles.js @@ -1,9 +1,9 @@ -const dotenv = require("dotenv") +const dotenv = require('dotenv') dotenv.config({ path: './.env.test' }) //mock lib/log since encoding characters from chalk makes testing difficult jest.mock('./lib/log', () => { - console.log("Setting up mocked log") + console.log('Setting up mocked log') return { _esModule: false, info: (...message) => console.log(...message), @@ -11,4 +11,4 @@ jest.mock('./lib/log', () => { error: (...message) => console.log(...message), warn: (...message) => console.log(...message), } -}) \ No newline at end of file +}) diff --git a/jest.setupFilesAfterEnv.js b/jest.setupFilesAfterEnv.js index c92632a..3ac5935 100644 --- a/jest.setupFilesAfterEnv.js +++ b/jest.setupFilesAfterEnv.js @@ -3,7 +3,7 @@ const Path = require('path') beforeAll(() => { let migrationsDir = process.env.MIGRATIONS_DIR - if (!fs.existsSync(migrationsDir)){ + if (!fs.existsSync(migrationsDir)) { fs.mkdirSync(migrationsDir) } }) diff --git a/lib/env.js b/lib/env.js index c9aa381..1d885a6 100644 --- a/lib/env.js +++ b/lib/env.js @@ -3,7 +3,7 @@ const defaults = { APPLIED_MIGRATIONS_TYPE_ID: 'appliedMigrations', MAX_NUMBER_OF_ENVIRONMENTS: 4, MAX_NUMBER_OF_ALIASES: 1, - NUMBER_OF_RETRIES_WHEN_CREATING_ENVIRONMENT: 10 + NUMBER_OF_RETRIES_WHEN_CREATING_ENVIRONMENT: 10, } module.exports = (name) => { diff --git a/mocks/contentful/baseContentfulHandler.js b/mocks/contentful/baseContentfulHandler.js index 47a6ee3..71338e9 100644 --- a/mocks/contentful/baseContentfulHandler.js +++ b/mocks/contentful/baseContentfulHandler.js @@ -1,6 +1,6 @@ -const {setupServer} = require('msw/node') -const log = require("../../lib/log") -const {rest} = require("msw") +const { setupServer } = require('msw/node') +const log = require('../../lib/log') +const { rest } = require('msw') let mockedContentfulServer = null @@ -11,32 +11,32 @@ module.exports.setupMockedContentfulApi = (handlers) => { handlers = [] } let totalNumberOfRequests = 0 - log.info("setting up mocked contentful rest server") + log.info('setting up mocked contentful rest server') const server = setupServer(...spacesHandler, ...localeHandler, ...masterEnvironmentHandler, ...handlers) //log unhandled requests server.listen({ onUnhandledRequest(req) { - log.warn(`* Found an unhandled ${req.method} request to ${req.url.href}`,) + log.warn(`* Found an unhandled ${req.method} request to ${req.url.href}`) }, }) process.on('exit', () => { - log.info("handling exit...") + log.info('handling exit...') }) server.events.on('request:start', (request, response) => { // Record every dispatched request. - log.info(`* intercepting ${request.method} request to ${request.url}`,) + log.info(`* intercepting ${request.method} request to ${request.url}`) totalNumberOfRequests++ - log.info('Total number of requests: ' , totalNumberOfRequests) + log.info('Total number of requests: ', totalNumberOfRequests) }) mockedContentfulServer = server } module.exports.closeMockedContentfulApi = () => { - console.log("CLOSING MOCKED CONTENTFUL SERVER") + console.log('CLOSING MOCKED CONTENTFUL SERVER') if (mockedContentfulServer != null) { mockedContentfulServer.close() } @@ -44,28 +44,19 @@ module.exports.closeMockedContentfulApi = () => { const spacesHandler = [ rest.get(`${this.baseURL}`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json(spacesResponseBody), - ) + return res(ctx.status(200), ctx.json(spacesResponseBody)) }), ] const localeHandler = [ rest.get(`${this.baseURL}/environments/master/locales`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json(localeResponseBody), - ) + return res(ctx.status(200), ctx.json(localeResponseBody)) }), ] const masterEnvironmentHandler = [ rest.get(`${this.baseURL}/environments/master`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json(masterEnvironmentResponseBody), - ) + return res(ctx.status(200), ctx.json(masterEnvironmentResponseBody)) }), ] @@ -73,138 +64,138 @@ const masterEnvironmentHandler = [ //https://api.contentful.com/spaces/TEST_SPACE_ID const spacesResponseBody = { - "name": "spaceName", - "sys": { - "type": "Space", - "id": "TEST_SPACE_ID", - "version": 7, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + name: 'spaceName', + sys: { + type: 'Space', + id: 'TEST_SPACE_ID', + version: 7, + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "createdAt": "2018-09-17T08:26:06Z", - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + createdAt: '2018-09-17T08:26:06Z', + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "updatedAt": "2022-12-15T09:11:48Z", - "organization": { - "sys": { - "type": "Link", - "linkType": "Organization", - "id": "1kUUWhojvGtUmRyhXfqSwK" - } - } - } + updatedAt: '2022-12-15T09:11:48Z', + organization: { + sys: { + type: 'Link', + linkType: 'Organization', + id: '1kUUWhojvGtUmRyhXfqSwK', + }, + }, + }, } //https://api.contentful.com/spaces/TEST_SPACE_ID/environments/master/locales const localeResponseBody = { - "sys": { - "type": "Array" + sys: { + type: 'Array', }, - "total": 1, - "skip": 0, - "limit": 100, - "items": [ + total: 1, + skip: 0, + limit: 100, + items: [ { - "name": "English (United States)", - "internal_code": "en-US", - "code": "en-US", - "fallbackCode": null, - "default": true, - "contentManagementApi": true, - "contentDeliveryApi": true, - "optional": false, - "sys": { - "type": "Locale", - "id": "1VDLlb9oKX4EE2oI6p9kMa", - "version": 1, - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } + name: 'English (United States)', + internal_code: 'en-US', + code: 'en-US', + fallbackCode: null, + default: true, + contentManagementApi: true, + contentDeliveryApi: true, + optional: false, + sys: { + type: 'Locale', + id: '1VDLlb9oKX4EE2oI6p9kMa', + version: 1, + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, }, - "environment": { - "sys": { - "type": "Link", - "linkType": "Environment", - "id": "2023-06-14-08-27-25", - "uuid": "94b6a504-e87c-4d55-9ec0-4a43142e4dfc" - } + environment: { + sys: { + type: 'Link', + linkType: 'Environment', + id: '2023-06-14-08-27-25', + uuid: '94b6a504-e87c-4d55-9ec0-4a43142e4dfc', + }, }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "createdAt": "2023-06-14T08:27:26Z", - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + createdAt: '2023-06-14T08:27:26Z', + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "updatedAt": "2023-06-14T08:27:26Z" - } - } - ] + updatedAt: '2023-06-14T08:27:26Z', + }, + }, + ], } //https://api.contentful.com/spaces/TEST_SPACE_ID/environments/master const masterEnvironmentResponseBody = { - "name": "2023-06-14-08-27-25", - "sys": { - "type": "Environment", - "id": "master", - "aliasedEnvironment": { - "sys": { - "type": "Link", - "linkType": "Environment", - "id": "2023-06-14-08-27-25" - } + name: '2023-06-14-08-27-25', + sys: { + type: 'Environment', + id: 'master', + aliasedEnvironment: { + sys: { + type: 'Link', + linkType: 'Environment', + id: '2023-06-14-08-27-25', + }, }, - "version": 3, - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } + version: 3, + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, }, - "status": { - "sys": { - "type": "Link", - "linkType": "Status", - "id": "ready" - } + status: { + sys: { + type: 'Link', + linkType: 'Status', + id: 'ready', + }, }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "createdAt": "2023-06-14T08:27:26Z", - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } + createdAt: '2023-06-14T08:27:26Z', + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, }, - "updatedAt": "2023-06-14T08:27:26Z" - } -} \ No newline at end of file + updatedAt: '2023-06-14T08:27:26Z', + }, +} diff --git a/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js b/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js index cefef87..01f0e40 100644 --- a/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js +++ b/mocks/contentful/handlers/list/noAppliedMigrationsHandler.js @@ -1,141 +1,138 @@ -const {rest} = require("msw") -const {baseURL} = require("../../baseContentfulHandler") +const { rest } = require('msw') +const { baseURL } = require('../../baseContentfulHandler') module.exports.listNoAppliedMigrationHandler = [ rest.get(`${baseURL}/environments/master/entries`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json(body), - ) + return res(ctx.status(200), ctx.json(body)) }), ] const body = { - "sys": { - "type": "Array" + sys: { + type: 'Array', }, - "total": 2, - "skip": 0, - "limit": 1000, - "items": [ + total: 2, + skip: 0, + limit: 1000, + items: [ { - "metadata": { - "tags": [] + metadata: { + tags: [], }, - "sys": { - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } - }, - "id": "5UALu1mPBVs3arGpz6BQOS", - "type": "Entry", - "createdAt": "2023-06-26T13:47:13.646Z", - "updatedAt": "2023-06-26T13:47:13.646Z", - "environment": { - "sys": { - "id": "master", - "type": "Link", - "linkType": "Environment" - } - }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "publishedCounter": 0, - "version": 1, - "automationTags": [], - "contentType": { - "sys": { - "type": "Link", - "linkType": "ContentType", - "id": "appliedMigrations" - } - } + sys: { + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, + }, + id: '5UALu1mPBVs3arGpz6BQOS', + type: 'Entry', + createdAt: '2023-06-26T13:47:13.646Z', + updatedAt: '2023-06-26T13:47:13.646Z', + environment: { + sys: { + id: 'master', + type: 'Link', + linkType: 'Environment', + }, + }, + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + publishedCounter: 0, + version: 1, + automationTags: [], + contentType: { + sys: { + type: 'Link', + linkType: 'ContentType', + id: 'appliedMigrations', + }, + }, }, - "fields": { - "timestamp": { - "en-US": "20230602075003097 (1)" + fields: { + timestamp: { + 'en-US': '20230602075003097 (1)', }, - "name": { - "en-US": "inititial-migration" + name: { + 'en-US': 'inititial-migration', }, - "batch": { - "en-US": 1 - } - } + batch: { + 'en-US': 1, + }, + }, }, { - "metadata": { - "tags": [] + metadata: { + tags: [], }, - "sys": { - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } - }, - "id": "6iq3xP0EsGS9NzJoWvyblp", - "type": "Entry", - "createdAt": "2023-06-26T13:47:12.064Z", - "updatedAt": "2023-06-26T13:47:12.064Z", - "environment": { - "sys": { - "id": "master", - "type": "Link", - "linkType": "Environment" - } - }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "publishedCounter": 0, - "version": 1, - "automationTags": [], - "contentType": { - "sys": { - "type": "Link", - "linkType": "ContentType", - "id": "appliedMigrations" - } - } + sys: { + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, + }, + id: '6iq3xP0EsGS9NzJoWvyblp', + type: 'Entry', + createdAt: '2023-06-26T13:47:12.064Z', + updatedAt: '2023-06-26T13:47:12.064Z', + environment: { + sys: { + id: 'master', + type: 'Link', + linkType: 'Environment', + }, + }, + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + publishedCounter: 0, + version: 1, + automationTags: [], + contentType: { + sys: { + type: 'Link', + linkType: 'ContentType', + id: 'appliedMigrations', + }, + }, + }, + fields: { + timestamp: { + 'en-US': '20230602075003097 (1)', + }, + name: { + 'en-US': 'inititial-migration', + }, + batch: { + 'en-US': 1, + }, }, - "fields": { - "timestamp": { - "en-US": "20230602075003097 (1)" - }, - "name": { - "en-US": "inititial-migration" - }, - "batch": { - "en-US": 1 - } - } - } - ] -} \ No newline at end of file + }, + ], +} diff --git a/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js b/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js index 6918304..c579455 100644 --- a/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js +++ b/mocks/contentful/handlers/list/oneAppliedMigrationsHandler.js @@ -1,212 +1,209 @@ -const {rest} = require("msw") -const {baseURL} = require("../../baseContentfulHandler") +const { rest } = require('msw') +const { baseURL } = require('../../baseContentfulHandler') module.exports.listOneMigrationAppliedHandler = [ rest.get(`${baseURL}/environments/master/entries`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json(body), - ) + return res(ctx.status(200), ctx.json(body)) }), ] const body = { - "sys": { - "type": "Array" + sys: { + type: 'Array', }, - "total": 3, - "skip": 0, - "limit": 1000, - "items": [ + total: 3, + skip: 0, + limit: 1000, + items: [ { - "metadata": { - "tags": [] + metadata: { + tags: [], }, - "sys": { - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } - }, - "id": "KIDj4LUFhTnEqWE3vEaGa", - "type": "Entry", - "createdAt": "2023-06-26T14:12:42.866Z", - "updatedAt": "2023-06-26T14:12:43.400Z", - "environment": { - "sys": { - "id": "master", - "type": "Link", - "linkType": "Environment" - } - }, - "publishedVersion": 1, - "publishedAt": "2023-06-26T14:12:43.400Z", - "firstPublishedAt": "2023-06-26T14:12:43.400Z", - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "publishedCounter": 1, - "version": 2, - "publishedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "automationTags": [], - "contentType": { - "sys": { - "type": "Link", - "linkType": "ContentType", - "id": "appliedMigrations" - } - } + sys: { + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, + }, + id: 'KIDj4LUFhTnEqWE3vEaGa', + type: 'Entry', + createdAt: '2023-06-26T14:12:42.866Z', + updatedAt: '2023-06-26T14:12:43.400Z', + environment: { + sys: { + id: 'master', + type: 'Link', + linkType: 'Environment', + }, + }, + publishedVersion: 1, + publishedAt: '2023-06-26T14:12:43.400Z', + firstPublishedAt: '2023-06-26T14:12:43.400Z', + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + publishedCounter: 1, + version: 2, + publishedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + automationTags: [], + contentType: { + sys: { + type: 'Link', + linkType: 'ContentType', + id: 'appliedMigrations', + }, + }, }, - "fields": { - "timestamp": { - "en-US": "20230609122547608" + fields: { + timestamp: { + 'en-US': '20230609122547608', + }, + name: { + 'en-US': 'new-migration', }, - "name": { - "en-US": "new-migration" + batch: { + 'en-US': 2, }, - "batch": { - "en-US": 2 - } - } + }, }, { - "metadata": { - "tags": [] + metadata: { + tags: [], }, - "sys": { - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } - }, - "id": "5UALu1mPBVs3arGpz6BQOS", - "type": "Entry", - "createdAt": "2023-06-26T13:47:13.646Z", - "updatedAt": "2023-06-26T13:47:13.646Z", - "environment": { - "sys": { - "id": "master", - "type": "Link", - "linkType": "Environment" - } - }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "publishedCounter": 0, - "version": 1, - "automationTags": [], - "contentType": { - "sys": { - "type": "Link", - "linkType": "ContentType", - "id": "appliedMigrations" - } - } + sys: { + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, + }, + id: '5UALu1mPBVs3arGpz6BQOS', + type: 'Entry', + createdAt: '2023-06-26T13:47:13.646Z', + updatedAt: '2023-06-26T13:47:13.646Z', + environment: { + sys: { + id: 'master', + type: 'Link', + linkType: 'Environment', + }, + }, + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + publishedCounter: 0, + version: 1, + automationTags: [], + contentType: { + sys: { + type: 'Link', + linkType: 'ContentType', + id: 'appliedMigrations', + }, + }, }, - "fields": { - "timestamp": { - "en-US": "20230602075003097 (1)" + fields: { + timestamp: { + 'en-US': '20230602075003097 (1)', + }, + name: { + 'en-US': 'inititial-migration', }, - "name": { - "en-US": "inititial-migration" + batch: { + 'en-US': 1, }, - "batch": { - "en-US": 1 - } - } + }, }, { - "metadata": { - "tags": [] + metadata: { + tags: [], }, - "sys": { - "space": { - "sys": { - "type": "Link", - "linkType": "Space", - "id": "TEST_SPACE_ID" - } - }, - "id": "6iq3xP0EsGS9NzJoWvyblp", - "type": "Entry", - "createdAt": "2023-06-26T13:47:12.064Z", - "updatedAt": "2023-06-26T13:47:12.064Z", - "environment": { - "sys": { - "id": "master", - "type": "Link", - "linkType": "Environment" - } - }, - "createdBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "updatedBy": { - "sys": { - "type": "Link", - "linkType": "User", - "id": "7fkm1bGT9u8nLkbD7Uuqsr" - } - }, - "publishedCounter": 0, - "version": 1, - "automationTags": [], - "contentType": { - "sys": { - "type": "Link", - "linkType": "ContentType", - "id": "appliedMigrations" - } - } + sys: { + space: { + sys: { + type: 'Link', + linkType: 'Space', + id: 'TEST_SPACE_ID', + }, + }, + id: '6iq3xP0EsGS9NzJoWvyblp', + type: 'Entry', + createdAt: '2023-06-26T13:47:12.064Z', + updatedAt: '2023-06-26T13:47:12.064Z', + environment: { + sys: { + id: 'master', + type: 'Link', + linkType: 'Environment', + }, + }, + createdBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + updatedBy: { + sys: { + type: 'Link', + linkType: 'User', + id: '7fkm1bGT9u8nLkbD7Uuqsr', + }, + }, + publishedCounter: 0, + version: 1, + automationTags: [], + contentType: { + sys: { + type: 'Link', + linkType: 'ContentType', + id: 'appliedMigrations', + }, + }, + }, + fields: { + timestamp: { + 'en-US': '20230602075003097 (1)', + }, + name: { + 'en-US': 'inititial-migration', + }, + batch: { + 'en-US': 1, + }, }, - "fields": { - "timestamp": { - "en-US": "20230602075003097 (1)" - }, - "name": { - "en-US": "inititial-migration" - }, - "batch": { - "en-US": 1 - } - } - } - ] -} \ No newline at end of file + }, + ], +} diff --git a/traffic/interceptor.js b/traffic/interceptor.js index 813ba0b..b830fea 100644 --- a/traffic/interceptor.js +++ b/traffic/interceptor.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const {rest} = require('msw') +const { rest } = require('msw') const fs = require('fs') const path = require('path') -const {setupServer} = require('msw/node') -const log = require("../lib/log") +const { setupServer } = require('msw/node') +const log = require('../lib/log') const requests = new Map() const transactions = new Set() @@ -12,47 +12,40 @@ const server = setupServer() //this utility can be used to record all network traffic. // Each request and response during app lifetime is logged to json in the traffic/output directory. //run setupInterceptorServer() in bin/cmp.js for this to work. -module.exports.setupInterceptorServer = ({logUnhandledRequests, logBypassedTraffic, saveTrafficToFile}) => { - log.info("setting up network traffic interceptor server") +module.exports.setupInterceptorServer = ({ logUnhandledRequests, logBypassedTraffic, saveTrafficToFile }) => { + log.info('setting up network traffic interceptor server') //catch requests from underlying dependencies - if(logUnhandledRequests){ + if (logUnhandledRequests) { server.listen({ onUnhandledRequest(req) { - log.warn( - `* Found an unhandled ${req.method} request to ${req.url.href}`, - ) + log.warn(`* Found an unhandled ${req.method} request to ${req.url.href}`) }, }) } - if(logBypassedTraffic){ + if (logBypassedTraffic) { server.events.on('request:start', (request, response) => { // Record every dispatched request. - log.info( - `* intercepting ${request.method} request to ${request.url}`, - ) + log.info(`* intercepting ${request.method} request to ${request.url}`) requests.set(request.id, request) transactions.add([request, response]) }) -// Since we're not providing any request handlers -// to the "setupServer" call, all responses will be -// bypassed (performed as-is). This will allow us to -// collect the actual responses. + // Since we're not providing any request handlers + // to the "setupServer" call, all responses will be + // bypassed (performed as-is). This will allow us to + // collect the actual responses. server.events.on('response:bypass', (response, requestId) => { - log.info( - `* receiving status ${response.status} from ${requests.get(requestId).url}`, - ) + log.info(`* receiving status ${response.status} from ${requests.get(requestId).url}`) const request = requests.get(requestId) transactions.add([request, response]) }) } - process.on('exit', () => { - log.info("handling exit") - if(saveTrafficToFile){ + log.info('handling exit') + if (saveTrafficToFile) { this.writeTrafficToFile() } }) @@ -61,15 +54,12 @@ module.exports.setupInterceptorServer = ({logUnhandledRequests, logBypassedTraff module.exports.writeTrafficToFile = () => { const json = [] for (const [request, response] of transactions.entries()) { - json.push({request, response}) + json.push({ request, response }) } let currentTime = new Date().getTime().toString() let filePath = path.resolve(__dirname, `output/traffic-${currentTime}.json`) let jsonString = JSON.stringify(json, null, 2) - fs.writeFileSync( - filePath, - jsonString, - ) + fs.writeFileSync(filePath, jsonString) } From 56cc9c43a434463de3f089a1384dce01b73fee56 Mon Sep 17 00:00:00 2001 From: driatic Date: Thu, 13 Jul 2023 11:10:54 +0200 Subject: [PATCH 4/5] feat: add simple reset test --- __tests__/reset.test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 __tests__/reset.test.js diff --git a/__tests__/reset.test.js b/__tests__/reset.test.js new file mode 100644 index 0000000..da4fa2c --- /dev/null +++ b/__tests__/reset.test.js @@ -0,0 +1,11 @@ +const { handler: resetCommand } = require('../bin/commands/reset') +const { extractLogLinesFromConsole } = require('../__test-utils__/log') +const { handler: migrateCommand } = require('../bin/commands/migrate') + +describe('reset', () => { + it('should not reset environment if on master', async () => { + const stdout = extractLogLinesFromConsole() + await resetCommand({ force: false }) + expect(stdout).toContain(`Can't reset environment if you are on master.`) + }) +}) From 0e55e4517aaae103509d05a4b8af9be14581c4a0 Mon Sep 17 00:00:00 2001 From: driatic Date: Thu, 13 Jul 2023 11:38:47 +0200 Subject: [PATCH 5/5] feat: fixes --- __tests__/generate.test.js | 1 - __tests__/migrate.test.js | 1 - __tests__/reset.test.js | 1 - bin/cmp.js | 3 --- 4 files changed, 6 deletions(-) diff --git a/__tests__/generate.test.js b/__tests__/generate.test.js index dd68a46..e1e4034 100644 --- a/__tests__/generate.test.js +++ b/__tests__/generate.test.js @@ -1,4 +1,3 @@ -const { execaNode } = require('execa') const fs = require('fs') const { join } = require('path') const { handler: generateCommand } = require('../bin/commands/generate') diff --git a/__tests__/migrate.test.js b/__tests__/migrate.test.js index 9d73dbc..be8dbe3 100644 --- a/__tests__/migrate.test.js +++ b/__tests__/migrate.test.js @@ -1,4 +1,3 @@ -const { execaNode } = require('execa') const { handler: migrateCommand } = require('../bin/commands/migrate') const { extractLogLinesFromConsole } = require('../__test-utils__/log') const { setupMockedContentfulApi, closeMockedContentfulApi } = require('../mocks/contentful/baseContentfulHandler') diff --git a/__tests__/reset.test.js b/__tests__/reset.test.js index da4fa2c..e9dcc3e 100644 --- a/__tests__/reset.test.js +++ b/__tests__/reset.test.js @@ -1,6 +1,5 @@ const { handler: resetCommand } = require('../bin/commands/reset') const { extractLogLinesFromConsole } = require('../__test-utils__/log') -const { handler: migrateCommand } = require('../bin/commands/migrate') describe('reset', () => { it('should not reset environment if on master', async () => { diff --git a/bin/cmp.js b/bin/cmp.js index a4f69cc..c719f55 100755 --- a/bin/cmp.js +++ b/bin/cmp.js @@ -1,8 +1,5 @@ #!/usr/bin/env node -const { setupInterceptorServer } = require('../traffic/interceptor') -setupInterceptorServer({ logUnhandledRequests: true }) - require('yargs') .usage('Contentful migration tooling.') .commandDir('commands')