diff --git a/.changeset/strange-flies-retire.md b/.changeset/strange-flies-retire.md new file mode 100644 index 00000000000..7c96e4bf163 --- /dev/null +++ b/.changeset/strange-flies-retire.md @@ -0,0 +1,6 @@ +--- +'@keystonejs/keystone': patch +'@keystonejs/test-utils': minor +--- + +Moved adapter mocks into test utils package. diff --git a/packages/keystone/package.json b/packages/keystone/package.json index 597b1e846f4..0fc5c0a4432 100644 --- a/packages/keystone/package.json +++ b/packages/keystone/package.json @@ -40,6 +40,7 @@ "terminal-link": "^1.3.0" }, "devDependencies": { + "@keystonejs/test-utils": "*", "p-is-promise": "^3.0.0", "tmp": "^0.2.1" }, diff --git a/packages/keystone/tests/List.test.js b/packages/keystone/tests/List.test.js index 6eac791787d..863d56464b5 100644 --- a/packages/keystone/tests/List.test.js +++ b/packages/keystone/tests/List.test.js @@ -1,5 +1,6 @@ const gql = require('graphql-tag'); const { print } = require('graphql/language/printer'); +const { MockAdapter, MockIdType, MockListAdapter } = require('@keystonejs/test-utils'); // We don't want to actually log, so we mock it before we require the class jest.doMock('@keystonejs/logger', () => ({ @@ -17,130 +18,6 @@ function resolveViewPath(viewPath) { return path.join(fieldsPackagePath, 'src', 'types', viewPath); } -class MockFieldImplementation { - constructor() { - this.access = { - public: { - create: false, - read: true, - update: false, - delete: false, - }, - }; - this.config = {}; - this.hooks = {}; - } - getAdminMeta() { - return { path: 'id' }; - } - gqlOutputFields() { - return ['id: ID']; - } - gqlQueryInputFields() { - return ['id: ID']; - } - get gqlUpdateInputFields() { - return ['id: ID']; - } - get gqlCreateInputFields() { - return ['id: ID']; - } - getGqlAuxTypes() { - return []; - } - getGqlAuxQueries() { - return []; - } - getGqlAuxMutations() { - return []; - } - gqlOutputFieldResolvers() { - return {}; - } - gqlAuxQueryResolvers() { - return {}; - } - gqlAuxMutationResolvers() { - return {}; - } - gqlAuxFieldResolvers() { - return {}; - } - extendAdminViews(views) { - return views; - } - getDefaultValue() { - return; - } - async resolveInput({ resolvedData }) { - return resolvedData.id; - } - async validateInput() {} - async beforeChange() {} - async afterChange() {} - async beforeDelete() {} - async validateDelete() {} - async afterDelete() {} -} -class MockFieldAdapter {} - -const MockIdType = { - implementation: MockFieldImplementation, - views: {}, - adapters: { mock: MockFieldAdapter }, -}; - -class MockListAdapter { - name = 'mock'; - constructor(parentAdapter) { - this.parentAdapter = parentAdapter; - this.index = 3; - this.items = { - 0: { name: 'a', email: 'a@example.com', index: 0 }, - 1: { name: 'b', email: 'b@example.com', index: 1 }, - 2: { name: 'c', email: 'c@example.com', index: 2 }, - }; - } - newFieldAdapter = () => new MockFieldAdapter(); - create = async item => { - this.items[this.index] = { - ...item, - index: this.index, - }; - this.index += 1; - return this.items[this.index - 1]; - }; - findById = id => this.items[id]; - delete = async id => { - this.items[id] = undefined; - }; - itemsQuery = async ({ where: { id_in: ids, id, id_not_in } }, { meta = false } = {}) => { - if (meta) { - return { - count: (id !== undefined - ? [this.items[id]] - : ids.filter(i => !id_not_in || !id_not_in.includes(i)).map(i => this.items[i]) - ).length, - }; - } else { - return id !== undefined - ? [this.items[id]] - : ids.filter(i => !id_not_in || !id_not_in.includes(i)).map(i => this.items[i]); - } - }; - itemsQueryMeta = async args => this.itemsQuery(args, { meta: true }); - update = (id, item) => { - this.items[id] = { ...this.items[id], ...item }; - return this.items[id]; - }; -} - -class MockAdapter { - name = 'mock'; - newListAdapter = () => new MockListAdapter(this); - getDefaultPrimaryKeyConfig = () => ({ type: MockIdType }); -} - Text.adapters['mock'] = {}; Checkbox.adapters['mock'] = {}; Float.adapters['mock'] = {}; diff --git a/packages/test-utils/index.js b/packages/test-utils/index.js index ea8bba6bb34..b0a299f26ca 100644 --- a/packages/test-utils/index.js +++ b/packages/test-utils/index.js @@ -5,6 +5,9 @@ const { authedGraphqlRequest, networkedGraphqlRequest, matchFilter, + MockAdapter, + MockListAdapter, + MockIdType, } = require('./lib/test-utils'); module.exports = { @@ -14,4 +17,7 @@ module.exports = { authedGraphqlRequest, networkedGraphqlRequest, matchFilter, + MockAdapter, + MockListAdapter, + MockIdType, }; diff --git a/packages/test-utils/lib/test-utils.js b/packages/test-utils/lib/test-utils.js index 695374993d1..d54860cb216 100644 --- a/packages/test-utils/lib/test-utils.js +++ b/packages/test-utils/lib/test-utils.js @@ -249,6 +249,130 @@ const matchFilter = ({ keystone, queryArgs, fieldSelection, expected, sortKey }) }); }; +class MockFieldImplementation { + constructor() { + this.access = { + public: { + create: false, + read: true, + update: false, + delete: false, + }, + }; + this.config = {}; + this.hooks = {}; + } + getAdminMeta() { + return { path: 'id' }; + } + gqlOutputFields() { + return ['id: ID']; + } + gqlQueryInputFields() { + return ['id: ID']; + } + get gqlUpdateInputFields() { + return ['id: ID']; + } + get gqlCreateInputFields() { + return ['id: ID']; + } + getGqlAuxTypes() { + return []; + } + getGqlAuxQueries() { + return []; + } + getGqlAuxMutations() { + return []; + } + gqlOutputFieldResolvers() { + return {}; + } + gqlAuxQueryResolvers() { + return {}; + } + gqlAuxMutationResolvers() { + return {}; + } + gqlAuxFieldResolvers() { + return {}; + } + extendAdminViews(views) { + return views; + } + getDefaultValue() { + return; + } + async resolveInput({ resolvedData }) { + return resolvedData.id; + } + async validateInput() {} + async beforeChange() {} + async afterChange() {} + async beforeDelete() {} + async validateDelete() {} + async afterDelete() {} +} +class MockFieldAdapter {} + +const MockIdType = { + implementation: MockFieldImplementation, + views: {}, + adapters: { mock: MockFieldAdapter }, +}; + +class MockListAdapter { + name = 'mock'; + constructor(parentAdapter) { + this.parentAdapter = parentAdapter; + this.index = 3; + this.items = { + 0: { name: 'a', email: 'a@example.com', index: 0 }, + 1: { name: 'b', email: 'b@example.com', index: 1 }, + 2: { name: 'c', email: 'c@example.com', index: 2 }, + }; + } + newFieldAdapter = () => new MockFieldAdapter(); + create = async item => { + this.items[this.index] = { + ...item, + index: this.index, + }; + this.index += 1; + return this.items[this.index - 1]; + }; + findById = id => this.items[id]; + delete = async id => { + this.items[id] = undefined; + }; + itemsQuery = async ({ where: { id_in: ids, id, id_not_in } }, { meta = false } = {}) => { + if (meta) { + return { + count: (id !== undefined + ? [this.items[id]] + : ids.filter(i => !id_not_in || !id_not_in.includes(i)).map(i => this.items[i]) + ).length, + }; + } else { + return id !== undefined + ? [this.items[id]] + : ids.filter(i => !id_not_in || !id_not_in.includes(i)).map(i => this.items[i]); + } + }; + itemsQueryMeta = async args => this.itemsQuery(args, { meta: true }); + update = (id, item) => { + this.items[id] = { ...this.items[id], ...item }; + return this.items[id]; + }; +} + +class MockAdapter { + name = 'mock'; + newListAdapter = () => new MockListAdapter(this); + getDefaultPrimaryKeyConfig = () => ({ type: MockIdType }); +} + module.exports = { setupServer, multiAdapterRunners, @@ -256,4 +380,7 @@ module.exports = { authedGraphqlRequest, networkedGraphqlRequest, matchFilter, + MockAdapter, + MockListAdapter, + MockIdType, };