diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a800560a2c..83b65c48ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -163,7 +163,7 @@ Before submitting an issue you need to make sure: - You have already searched for related [issues](https://github.com/strapi/strapi/issues), and found none open (if you found a related _closed_ issue, please link to it from your post). - You are not asking a question about how to use Strapi or about whether or not Strapi has a certain feature. For general help using Strapi, you may: - Refer to [the official Strapi documentation](https://strapi.io). - - Ask a member of the community in the [Strapi Slack Community](https://slack.strapi.io/). + - Ask a member of the community in the [Strapi Discord Community](https://discord.strapi.io/). - Ask a question on [our community forum](https://forum.strapi.io). - Your issue title is concise, on-topic and polite. - You can and do provide steps to reproduce your issue. diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 82b41d473a..d0b9118daa 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -5,7 +5,7 @@ services: image: postgres restart: always volumes: - - pgdata:/var/lib/postgresql/data + - pgdata_test:/var/lib/postgresql/data environment: POSTGRES_USER: strapi POSTGRES_PASSWORD: strapi @@ -24,10 +24,10 @@ services: MYSQL_ROOT_HOST: '%' MYSQL_ROOT_PASSWORD: strapi volumes: - - mysqldata:/var/lib/mysql + - mysqldata_test:/var/lib/mysql ports: - '3306:3306' volumes: - pgdata: - mysqldata: + pgdata_test: + mysqldata_test: diff --git a/examples/getstarted/config/database.js b/examples/getstarted/config/database.js index a597e5a73f..105242f5a6 100644 --- a/examples/getstarted/config/database.js +++ b/examples/getstarted/config/database.js @@ -10,7 +10,7 @@ const postgres = { client: 'postgres', connection: { database: 'strapi', - username: 'strapi', + user: 'strapi', password: 'strapi', port: 5432, host: 'localhost', @@ -22,7 +22,7 @@ const mysql = { client: 'mysql', connection: { database: 'strapi', - username: 'strapi', + user: 'strapi', password: 'strapi', port: 3306, host: 'localhost', diff --git a/package.json b/package.json index 08ae2cadee..bd16571fb9 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "test:front:update:ce": "cross-env NODE_ENV=test IS_EE=false jest --config ./jest.config.front.js --u", "test:snyk": "snyk test", "test:unit": "jest --verbose", - "test:e2e": "FORCE_COLOR=true jest --config jest.config.e2e.js --verbose --runInBand --testRunner=jest-circus/runner", + "test:e2e": "FORCE_COLOR=true jest --config jest.config.e2e.js --verbose --runInBand --testRunner=jest-circus/runner --forceExit --detectOpenHandles", "test:generate-app": "node test/create-test-app.js", "doc:api": "node scripts/open-api/serve.js" }, diff --git a/packages/cli/create-strapi-starter/package.json b/packages/cli/create-strapi-starter/package.json index 57f9588e61..aa0bc52e81 100644 --- a/packages/cli/create-strapi-starter/package.json +++ b/packages/cli/create-strapi-starter/package.json @@ -27,7 +27,7 @@ "node-fetch": "^2.6.1", "ora": "5.4.0", "@strapi/generate-new": "3.6.6", - "tar": "6.1.2" + "tar": "6.1.4" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/core/admin/admin/src/components/HeaderSearch/index.js b/packages/core/admin/admin/src/components/HeaderSearch/index.js index 52c7a5a785..ca2f5115e7 100644 --- a/packages/core/admin/admin/src/components/HeaderSearch/index.js +++ b/packages/core/admin/admin/src/components/HeaderSearch/index.js @@ -33,10 +33,10 @@ const HeaderSearch = ({ label, queryParameter }) => { // Create a new search in order to remove the filters currentSearch = new URLSearchParams(''); - // Keep the previous params _sort, pageSize, page + // Keep the previous params sort, pageSize, page const pageSize = query.get('pageSize'); const page = query.get('page'); - const _sort = query.get('_sort'); + const sort = query.get('sort'); if (page) { currentSearch.set('page', page); @@ -46,8 +46,8 @@ const HeaderSearch = ({ label, queryParameter }) => { currentSearch.set('pageSize', pageSize); } - if (_sort) { - currentSearch.set('_sort', _sort); + if (sort) { + currentSearch.set('sort', sort); } currentSearch.set(queryParameter, encodeURIComponent(value)); diff --git a/packages/core/admin/admin/src/components/Users/SortPicker/ListItem.js b/packages/core/admin/admin/src/components/Users/SortPicker/ListItem.js index 2ad417f7b8..ca5bc13440 100644 --- a/packages/core/admin/admin/src/components/Users/SortPicker/ListItem.js +++ b/packages/core/admin/admin/src/components/Users/SortPicker/ListItem.js @@ -8,7 +8,7 @@ const ListItem = ({ onClick, selectedItem, label, value }) => { const { formatMessage } = useIntl(); const handleClick = () => { - onClick({ target: { name: '_sort', value } }); + onClick({ target: { name: 'sort', value } }); }; return ( diff --git a/packages/core/admin/admin/src/content-manager/components/CustomTable/Headers/Header.js b/packages/core/admin/admin/src/content-manager/components/CustomTable/Headers/Header.js index da527ead83..20ef3dc030 100644 --- a/packages/core/admin/admin/src/content-manager/components/CustomTable/Headers/Header.js +++ b/packages/core/admin/admin/src/content-manager/components/CustomTable/Headers/Header.js @@ -4,9 +4,9 @@ import { Carret, useTracking } from '@strapi/helper-plugin'; import { useListView } from '../../../hooks'; const Header = ({ fieldSchema: { type }, metadatas: { label, sortable, mainField }, name }) => { - const { _sort, firstSortableHeader, setQuery } = useListView(); + const { sort, firstSortableHeader, setQuery } = useListView(); const { trackUsage } = useTracking(); - const [sortBy, sortOrder] = _sort.split(':'); + const [sortBy, sortOrder] = sort.split(':'); let sortField = name; let useRelation = false; @@ -29,7 +29,7 @@ const Header = ({ fieldSchema: { type }, metadatas: { label, sortable, mainField } setQuery({ - _sort: value, + sort: value, }); } }; diff --git a/packages/core/admin/admin/src/content-manager/components/SettingsViewWrapper/index.js b/packages/core/admin/admin/src/content-manager/components/SettingsViewWrapper/index.js index 00f95224b5..7426335d68 100644 --- a/packages/core/admin/admin/src/content-manager/components/SettingsViewWrapper/index.js +++ b/packages/core/admin/admin/src/content-manager/components/SettingsViewWrapper/index.js @@ -151,12 +151,12 @@ const SettingsViewWrapper = ({ kind, uid, } = modifiedData; - const _sort = `${defaultSortBy}:${defaultSortOrder}`; + const sort = `${defaultSortBy}:${defaultSortOrder}`; const goBackSearch = `${stringify( { page: 1, pageSize, - _sort, + sort, }, { encode: false } )}${pluginsQueryParams ? `&${pluginsQueryParams}` : ''}`; diff --git a/packages/core/admin/admin/src/content-manager/hooks/useFindRedirectionLink/tests/selectors.test.js b/packages/core/admin/admin/src/content-manager/hooks/useFindRedirectionLink/tests/selectors.test.js index 5bf17fbe23..7a95e0f7b0 100644 --- a/packages/core/admin/admin/src/content-manager/hooks/useFindRedirectionLink/tests/selectors.test.js +++ b/packages/core/admin/admin/src/content-manager/hooks/useFindRedirectionLink/tests/selectors.test.js @@ -15,7 +15,7 @@ describe('CONTENT MANAGER | Containers | CollectionTypeFormWrapper | selectors', { kind: 'collectionType', name: 'api::address.address', - search: 'page=1&pageSize=50&_sort=city:ASC&plugins[i18n][locale]=fr', + search: 'page=1&pageSize=50&sort=city:ASC&plugins[i18n][locale]=fr', title: 'Addresses', to: '/content-manager/collectionType/api::address.address', uid: 'api::address.address', @@ -23,7 +23,7 @@ describe('CONTENT MANAGER | Containers | CollectionTypeFormWrapper | selectors', { kind: 'collectionType', name: 'api::category.category', - search: 'page=1&pageSize=50&_sort=city:ASC&plugins[i18n][locale]=fr', + search: 'page=1&pageSize=50&sort=city:ASC&plugins[i18n][locale]=fr', title: 'Categories', to: '/content-manager/collectionType/api::category.category', uid: 'api::category.category', @@ -36,7 +36,7 @@ describe('CONTENT MANAGER | Containers | CollectionTypeFormWrapper | selectors', { kind: 'collectionType', name: 'api::address.address', - search: 'page=1&pageSize=50&_sort=city:ASC&plugins[i18n][locale]=fr', + search: 'page=1&pageSize=50&sort=city:ASC&plugins[i18n][locale]=fr', title: 'Addresses', to: '/content-manager/collectionType/api::address.address', uid: 'api::address.address', @@ -44,7 +44,7 @@ describe('CONTENT MANAGER | Containers | CollectionTypeFormWrapper | selectors', { kind: 'collectionType', name: 'api::category.category', - search: 'page=1&pageSize=50&_sort=city:ASC&plugins[i18n][locale]=fr', + search: 'page=1&pageSize=50&sort=city:ASC&plugins[i18n][locale]=fr', title: 'Categories', to: '/content-manager/collectionType/api::category.category', uid: 'api::category.category', diff --git a/packages/core/admin/admin/src/content-manager/pages/App/utils/generateModelsLinks.js b/packages/core/admin/admin/src/content-manager/pages/App/utils/generateModelsLinks.js index fcca79b1e1..a31025d8d8 100644 --- a/packages/core/admin/admin/src/content-manager/pages/App/utils/generateModelsLinks.js +++ b/packages/core/admin/admin/src/content-manager/pages/App/utils/generateModelsLinks.js @@ -23,7 +23,7 @@ const generateLinks = (links, type, configurations = []) => { const searchParams = { page: 1, pageSize: currentContentTypeConfig.settings.pageSize, - _sort: `${currentContentTypeConfig.settings.defaultSortBy}:${currentContentTypeConfig.settings.defaultSortOrder}`, + sort: `${currentContentTypeConfig.settings.defaultSortBy}:${currentContentTypeConfig.settings.defaultSortOrder}`, }; search = stringify(searchParams, { encode: false }); diff --git a/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/generateModelsLinks.test.js b/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/generateModelsLinks.test.js index 288f1f9b4e..180995026f 100644 --- a/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/generateModelsLinks.test.js +++ b/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/generateModelsLinks.test.js @@ -48,7 +48,7 @@ describe('ADMIN | LeftMenu | utils', () => { { to: '/content-manager/collectionType/api::address.address', isDisplayed: true, - search: `page=1&pageSize=2&_sort=name:ASC`, + search: `page=1&pageSize=2&sort=name:ASC`, permissions: [ { action: 'plugin::content-manager.explorer.create', diff --git a/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/getContentTypeLinks.js b/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/getContentTypeLinks.js index c8f3a99b61..65e993734d 100644 --- a/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/getContentTypeLinks.js +++ b/packages/core/admin/admin/src/content-manager/pages/App/utils/tests/getContentTypeLinks.js @@ -106,7 +106,7 @@ describe('checkPermissions', () => { subject: 'api::address.address', }, ], - search: 'page=1&pageSize=10&_sort=name:ASC', + search: 'page=1&pageSize=10&sort=name:ASC', }, { destination: '/content-manager/collectionType/api::article.article', diff --git a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js index e11f4636e2..f98839a369 100644 --- a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js +++ b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js @@ -122,7 +122,7 @@ function ListView({ return formatFiltersFromQuery(query); }, [query]); - const _sort = query._sort; + const sort = query.sort; const _q = query._q || ''; const label = contentType.info.label; @@ -382,7 +382,7 @@ function ListView({ <> { const queryParams = { page: '1', pageSize: '10', - _sort: 'name:ASC', + sort: 'name:ASC', }; const queryString = buildQueryString(queryParams); - expect(queryString).toBe('?page=1&pageSize=10&_sort=name:ASC'); + expect(queryString).toBe('?page=1&pageSize=10&sort=name:ASC'); }); it('creates a valid query string with default params & plugin options', () => { const queryParams = { page: '1', pageSize: '10', - _sort: 'name:ASC', + sort: 'name:ASC', plugins: { i18n: { locale: 'en' }, }, @@ -25,27 +25,27 @@ describe('buildQueryString', () => { const queryString = buildQueryString(queryParams); - expect(queryString).toBe('?page=1&pageSize=10&_sort=name:ASC&_locale=en'); + expect(queryString).toBe('?page=1&pageSize=10&sort=name:ASC&_locale=en'); }); it('creates a valid query string with a _where clause', () => { const queryParams = { page: '1', pageSize: '10', - _sort: 'name:ASC', + sort: 'name:ASC', _where: [{ name: 'hello world' }], }; const queryString = buildQueryString(queryParams); - expect(queryString).toBe('?page=1&pageSize=10&_sort=name:ASC&_where[0][name]=hello world'); + expect(queryString).toBe('?page=1&pageSize=10&sort=name:ASC&_where[0][name]=hello world'); }); it('creates a valid query string with a _where and plugin options', () => { const queryParams = { page: '1', pageSize: '10', - _sort: 'name:ASC', + sort: 'name:ASC', _where: [{ name: 'hello world' }], plugins: { i18n: { locale: 'en' }, @@ -55,7 +55,7 @@ describe('buildQueryString', () => { const queryString = buildQueryString(queryParams); expect(queryString).toBe( - '?page=1&pageSize=10&_sort=name:ASC&_where[0][name]=hello world&_locale=en' + '?page=1&pageSize=10&sort=name:ASC&_where[0][name]=hello world&_locale=en' ); }); }); diff --git a/packages/core/admin/admin/src/hooks/useSettingsMenu/init.js b/packages/core/admin/admin/src/hooks/useSettingsMenu/init.js index 9ac5de5c8d..3b5c7a27b9 100644 --- a/packages/core/admin/admin/src/hooks/useSettingsMenu/init.js +++ b/packages/core/admin/admin/src/hooks/useSettingsMenu/init.js @@ -30,7 +30,7 @@ const init = (initialState, settings) => { { intlLabel: { id: 'Settings.permissions.menu.link.users.label' }, // Init the search params directly - to: '/settings/users?pageSize=10&page=1&_sort=firstname%3AASC', + to: '/settings/users?pageSize=10&page=1&sort=firstname', id: 'users', isDisplayed: false, permissions: adminPermissions.settings.users.main, diff --git a/packages/core/admin/admin/src/pages/MarketplacePage/PluginBanner/Wrapper.js b/packages/core/admin/admin/src/pages/MarketplacePage/PluginBanner/Wrapper.js index 4870210d29..a86e131434 100644 --- a/packages/core/admin/admin/src/pages/MarketplacePage/PluginBanner/Wrapper.js +++ b/packages/core/admin/admin/src/pages/MarketplacePage/PluginBanner/Wrapper.js @@ -11,7 +11,6 @@ const Wrapper = styled.div` padding: 8px 16px; .bannerImage { - margin-right: 1rem; width: 48px; height: 48px; margin-right: 16px; diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/index.js index d3ce734a7f..947c7584a7 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/index.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/index.js @@ -50,7 +50,7 @@ const ListPage = () => { ] = useReducer(reducer, initialState, init); const pageSize = parseInt(query.get('pageSize') || 10, 10); const page = parseInt(query.get('page') || 0, 10); - const _sort = decodeURIComponent(query.get('_sort')); + const sort = decodeURIComponent(query.get('sort')); const _q = decodeURIComponent(query.get('_q') || ''); const getDataRef = useRef(); const listRef = useRef(); @@ -242,7 +242,7 @@ const ListPage = () => { <> - + diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/utils/getFilters.js b/packages/core/admin/admin/src/pages/Users/ListPage/utils/getFilters.js index a17cfb8254..29b451edce 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/utils/getFilters.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/utils/getFilters.js @@ -3,24 +3,24 @@ const getFilters = search => { const filters = []; // eslint-disable-next-line no-restricted-syntax - for (let pair of query.entries()) { - if (!['_sort', 'pageSize', 'page', '_q'].includes(pair[0])) { - const splitted = pair[0].split('_'); + for (let [key, queryValue] of query.entries()) { + if (!['sort', 'pageSize', 'page', '_q'].includes(key)) { + const splitted = key.split('_'); let filterName; let filterType; // Filter type === '=') if (splitted.length === 1) { filterType = '='; - filterName = pair[0]; + filterName = key; } else { filterType = `_${splitted[1]}`; filterName = splitted[0]; } - const value = decodeURIComponent(pair[1]); + const value = decodeURIComponent(queryValue); - filters.push({ displayName: filterName, name: pair[0], filter: filterType, value }); + filters.push({ displayName: filterName, name: key, filter: filterType, value }); } } diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/utils/tests/getFilters.test.js b/packages/core/admin/admin/src/pages/Users/ListPage/utils/tests/getFilters.test.js index fd47c4c04e..288dc82d06 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/utils/tests/getFilters.test.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/utils/tests/getFilters.test.js @@ -2,13 +2,13 @@ import getFilters from '../getFilters'; describe('ADMIN | CONTAINERS | USERS | ListPage | utils | getFilters', () => { it('should return an empty array if there is not filter', () => { - const search = '_q=test&_sort=firstname&page=1&pageSize=1'; + const search = '_q=test&sort=firstname&page=1&pageSize=1'; expect(getFilters(search)).toHaveLength(0); }); it('should handle the = filter correctly ', () => { - const search = '_sort=firstname&page=1&pageSize=1&firstname=test&firstname_ne=something'; + const search = 'sort=firstname&page=1&pageSize=1&firstname=test&firstname_ne=something'; const expected = [ { displayName: 'firstname', diff --git a/packages/core/admin/server/controllers/authentication.js b/packages/core/admin/server/controllers/authentication.js index a840224b0e..a04dbccc1d 100644 --- a/packages/core/admin/server/controllers/authentication.js +++ b/packages/core/admin/server/controllers/authentication.js @@ -135,7 +135,7 @@ module.exports = { roles: superAdminRole ? [superAdminRole.id] : [], }); - await strapi.telemetry.send('didCreateFirstAdmin'); + strapi.telemetry.send('didCreateFirstAdmin'); ctx.body = { data: { diff --git a/packages/core/admin/server/services/metrics.js b/packages/core/admin/server/services/metrics.js index d58255e19e..38bcf4fb96 100644 --- a/packages/core/admin/server/services/metrics.js +++ b/packages/core/admin/server/services/metrics.js @@ -5,11 +5,11 @@ const { getService } = require('../utils'); const sendDidInviteUser = async () => { const numberOfUsers = await getService('user').count(); const numberOfRoles = await getService('role').count(); - return strapi.telemetry.send('didInviteUser', { numberOfRoles, numberOfUsers }); + strapi.telemetry.send('didInviteUser', { numberOfRoles, numberOfUsers }); }; const sendDidUpdateRolePermissions = async () => { - return strapi.telemetry.send('didUpdateRolePermissions'); + strapi.telemetry.send('didUpdateRolePermissions'); }; module.exports = { diff --git a/packages/core/admin/server/services/user.js b/packages/core/admin/server/services/user.js index a996c5defc..a9baea855e 100644 --- a/packages/core/admin/server/services/user.js +++ b/packages/core/admin/server/services/user.js @@ -41,7 +41,7 @@ const create = async attributes => { .query('strapi::user') .create({ data: user, populate: ['roles'] }); - await getService('metrics').sendDidInviteUser(); + getService('metrics').sendDidInviteUser(); return createdUser; }; diff --git a/packages/core/content-manager/controllers/collection-types.js b/packages/core/content-manager/controllers/collection-types.js index 094de2548b..e9dc9aff46 100644 --- a/packages/core/content-manager/controllers/collection-types.js +++ b/packages/core/content-manager/controllers/collection-types.js @@ -62,6 +62,8 @@ module.exports = { const { model } = ctx.params; const { body } = ctx.request; + const totalEntries = await strapi.query(model).count(); + const entityManager = getService('entity-manager'); const permissionChecker = getService('permission-checker').create({ userAbility, model }); @@ -77,9 +79,12 @@ module.exports = { await wrapBadRequest(async () => { const entity = await entityManager.create(sanitizeFn(body), model); + ctx.body = permissionChecker.sanitizeOutput(entity); - await strapi.telemetry.send('didCreateFirstContentTypeEntry', { model }); + if (totalEntries === 0) { + strapi.telemetry.send('didCreateFirstContentTypeEntry', { model }); + } })(); }, diff --git a/packages/core/database/lib/lifecycles.js b/packages/core/database/lib/lifecycles.js index 85ee0b4192..5947543878 100644 --- a/packages/core/database/lib/lifecycles.js +++ b/packages/core/database/lib/lifecycles.js @@ -1,15 +1,15 @@ 'use strict'; const createLifecyclesManager = db => { + let subscribers = []; + const lifecycleManager = { - _subscribers: [], subscribe(subscriber) { // TODO: verify subscriber - - this._subscribers.push(subscriber); + subscribers.push(subscriber); return () => { - this._subscribers.splice(this._subscribers.indexOf(subscriber), 1); + subscribers.splice(subscribers.indexOf(subscriber), 1); }; }, @@ -24,10 +24,11 @@ const createLifecyclesManager = db => { }, async run(action, uid, properties) { - for (const subscriber of this._subscribers) { + for (const subscriber of subscribers) { if (typeof subscriber === 'function') { const event = this.createEvent(action, uid, properties); - return await subscriber(event); + await subscriber(event); + continue; } const hasAction = action in subscriber; @@ -42,7 +43,7 @@ const createLifecyclesManager = db => { }, clear() { - this._subscribers = []; + subscribers = []; }, }; diff --git a/packages/core/database/lib/query/helpers.js b/packages/core/database/lib/query/helpers.js index 162f5b1892..23b28b8f01 100644 --- a/packages/core/database/lib/query/helpers.js +++ b/packages/core/database/lib/query/helpers.js @@ -516,6 +516,10 @@ const applyPopulate = async (results, populate, ctx) => { const { db, uid, qb } = ctx; const meta = db.metadata.get(uid); + if (_.isEmpty(results)) { + return results; + } + for (const key in populate) { // NOTE: Omit limit & offset to avoid needing a query per result to avoid making too many queries const populateValue = _.pick( @@ -579,34 +583,16 @@ const applyPopulate = async (results, populate, ctx) => { } = joinTable.joinColumn; const alias = qb.getAlias(); + const joinColAlias = `${alias}.${joinColumnName}`; - if (isCount) { - const rows = await qb - .init(populateValue) - .join({ - alias: alias, - referencedTable: joinTable.name, - referencedColumn: joinTable.inverseJoinColumn.name, - rootColumn: joinTable.inverseJoinColumn.referencedColumn, - rootTable: qb.alias, - on: joinTable.on, - }) - .select([`${alias}.${joinColumnName}`, qb.raw('count(*) AS count')]) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) - .groupBy(`${alias}.${joinColumnName}`) - .execute({ mapResults: false }); - - const map = rows.reduce((map, row) => { - map[row[joinColumnName]] = { count: row.count }; - return map; - }, {}); + const referencedValues = _.uniq( + results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value)) + ); + if (_.isEmpty(referencedValues)) { results.forEach(result => { - result[key] = map[result[referencedColumnName]] || { count: 0 }; + result[key] = null; }); - continue; } @@ -620,10 +606,8 @@ const applyPopulate = async (results, populate, ctx) => { rootTable: qb.alias, on: joinTable.on, }) - .addSelect(`${alias}.${joinColumnName}`) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) + .addSelect(joinColAlias) + .where({ [joinColAlias]: referencedValues }) .execute({ mapResults: false }); const map = _.groupBy(joinColumnName, rows); @@ -681,8 +665,20 @@ const applyPopulate = async (results, populate, ctx) => { } = joinTable.joinColumn; const alias = qb.getAlias(); + const joinColAlias = `${alias}.${joinColumnName}`; + + const referencedValues = _.uniq( + results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value)) + ); if (isCount) { + if (_.isEmpty(referencedValues)) { + results.forEach(result => { + result[key] = { count: 0 }; + }); + continue; + } + const rows = await qb .init(populateValue) .join({ @@ -693,11 +689,9 @@ const applyPopulate = async (results, populate, ctx) => { rootTable: qb.alias, on: joinTable.on, }) - .select([`${alias}.${joinColumnName}`, qb.raw('count(*) AS count')]) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) - .groupBy(`${alias}.${joinColumnName}`) + .select([joinColAlias, qb.raw('count(*) AS count')]) + .where({ [joinColAlias]: referencedValues }) + .groupBy(joinColAlias) .execute({ mapResults: false }); const map = rows.reduce((map, row) => { @@ -712,6 +706,13 @@ const applyPopulate = async (results, populate, ctx) => { continue; } + if (_.isEmpty(referencedValues)) { + results.forEach(result => { + result[key] = []; + }); + continue; + } + const rows = await qb .init(populateValue) .join({ @@ -722,10 +723,8 @@ const applyPopulate = async (results, populate, ctx) => { rootTable: qb.alias, on: joinTable.on, }) - .addSelect(`${alias}.${joinColumnName}`) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) + .addSelect(joinColAlias) + .where({ [joinColAlias]: referencedValues }) .execute({ mapResults: false }); const map = _.groupBy(joinColumnName, rows); @@ -745,8 +744,19 @@ const applyPopulate = async (results, populate, ctx) => { const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn; const alias = qb.getAlias(); + const joinColAlias = `${alias}.${joinColumnName}`; + const referencedValues = _.uniq( + results.map(r => r[referencedColumnName]).filter(value => !_.isNil(value)) + ); if (isCount) { + if (_.isEmpty(referencedValues)) { + results.forEach(result => { + result[key] = { count: 0 }; + }); + continue; + } + const rows = await qb .init(populateValue) .join({ @@ -757,11 +767,9 @@ const applyPopulate = async (results, populate, ctx) => { rootTable: qb.alias, on: joinTable.on, }) - .select([`${alias}.${joinColumnName}`, qb.raw('count(*) AS count')]) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) - .groupBy(`${alias}.${joinColumnName}`) + .select([joinColAlias, qb.raw('count(*) AS count')]) + .where({ [joinColAlias]: referencedValues }) + .groupBy(joinColAlias) .execute({ mapResults: false }); const map = rows.reduce((map, row) => { @@ -776,6 +784,13 @@ const applyPopulate = async (results, populate, ctx) => { continue; } + if (_.isEmpty(referencedValues)) { + results.forEach(result => { + result[key] = []; + }); + continue; + } + const rows = await qb .init(populateValue) .join({ @@ -786,10 +801,8 @@ const applyPopulate = async (results, populate, ctx) => { rootTable: qb.alias, on: joinTable.on, }) - .addSelect(`${alias}.${joinColumnName}`) - .where({ - [`${alias}.${joinColumnName}`]: results.map(r => r[referencedColumnName]), - }) + .addSelect(joinColAlias) + .where({ [joinColAlias]: referencedValues }) .execute({ mapResults: false }); const map = _.groupBy(joinColumnName, rows); diff --git a/packages/core/database/lib/query/query-builder.js b/packages/core/database/lib/query/query-builder.js index 87776e49a5..1fe6bcfb3b 100644 --- a/packages/core/database/lib/query/query-builder.js +++ b/packages/core/database/lib/query/query-builder.js @@ -30,6 +30,13 @@ const createQueryBuilder = (uid, db) => { alias: getAlias(), getAlias, + select(args) { + state.type = 'select'; + state.select = _.castArray(args).map(col => this.aliasColumn(col)); + + return this; + }, + insert(data) { state.type = 'insert'; state.data = data; @@ -65,13 +72,6 @@ const createQueryBuilder = (uid, db) => { return this; }, - select(args) { - state.type = 'select'; - state.select = _.castArray(args).map(col => this.aliasColumn(col)); - - return this; - }, - addSelect(args) { state.select.push(..._.castArray(args).map(col => this.aliasColumn(col))); return this; diff --git a/packages/core/database/lib/schema/builder.js b/packages/core/database/lib/schema/builder.js index a82521d55a..846aee80b7 100644 --- a/packages/core/database/lib/schema/builder.js +++ b/packages/core/database/lib/schema/builder.js @@ -72,13 +72,18 @@ module.exports = db => ({ await db.connection.transaction(async trx => { await this.createTables(schemaDiff.tables.added, trx); - // TODO: drop foreign keys targeting delete tables + // drop all delete table foreign keys then delete the tables + for (const table of schemaDiff.tables.removed) { + debug(`Removing table foreign keys: ${table.name}`); + + const schemaBuilder = this.getSchemaBuilder(table, trx); + await dropTableForeignKeys(schemaBuilder, table); + } for (const table of schemaDiff.tables.removed) { debug(`Removing table: ${table.name}`); const schemaBuilder = this.getSchemaBuilder(table, trx); - // TODO: add cascading if possible await dropTable(schemaBuilder, table); } @@ -288,6 +293,8 @@ const dropColumn = (tableBuilder, column) => { const createTable = async (schemaBuilder, table) => { if (await schemaBuilder.hasTable(table.name)) { throw new Error(`Table already exists ${table.name}`); + + // TODO: alter the table instead } await schemaBuilder.createTable(table.name, tableBuilder => { @@ -299,6 +306,13 @@ const createTable = async (schemaBuilder, table) => { }); }; +/** + * Drops a table from a database + * @param {Knex.SchemaBuilder} schemaBuilder + * @param {Table} table + */ +const dropTable = (schemaBuilder, table) => schemaBuilder.dropTableIfExists(table.name); + /** * Creates a table foreign keys constraints * @param {SchemaBuilder} schemaBuilder @@ -312,8 +326,13 @@ const createTableForeignKeys = async (schemaBuilder, table) => { }; /** - * Drops a table from a database - * @param {Knex.SchemaBuilder} schemaBuilder + * Drops a table foreign keys constraints + * @param {SchemaBuilder} schemaBuilder * @param {Table} table */ -const dropTable = (schemaBuilder, table) => schemaBuilder.dropTableIfExists(table.name); +const dropTableForeignKeys = async (schemaBuilder, table) => { + // foreign keys + await schemaBuilder.table(table.name, tableBuilder => { + (table.foreignKeys || []).forEach(foreignKey => dropForeignKey(tableBuilder, foreignKey)); + }); +}; diff --git a/packages/core/helper-plugin/lib/src/utils/generateFiltersFromSearch.js b/packages/core/helper-plugin/lib/src/utils/generateFiltersFromSearch.js index 0a89086a33..5053ff5ce3 100644 --- a/packages/core/helper-plugin/lib/src/utils/generateFiltersFromSearch.js +++ b/packages/core/helper-plugin/lib/src/utils/generateFiltersFromSearch.js @@ -10,7 +10,7 @@ const generateFiltersFromSearch = search => { x => !x.includes('_limit') && !x.includes('_page') && - !x.includes('_sort') && + !x.includes('sort') && !x.includes('_start') && !x.includes('_q=') && x !== '' diff --git a/packages/core/helper-plugin/lib/src/utils/tests/generateFiltersFromSearch.test.js b/packages/core/helper-plugin/lib/src/utils/tests/generateFiltersFromSearch.test.js index 26ae3a6a8e..458078daaa 100644 --- a/packages/core/helper-plugin/lib/src/utils/tests/generateFiltersFromSearch.test.js +++ b/packages/core/helper-plugin/lib/src/utils/tests/generateFiltersFromSearch.test.js @@ -3,7 +3,7 @@ import generateFiltersFromSearch from '../generateFiltersFromSearch'; describe('HELPER PLUGIN | utils | generateFiltersFromSearch', () => { it('should generate an array of filters', () => { const search = - '?_sort=id:ASC&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; + '?sort=id:ASC&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; const expected = [ { name: 'bool', diff --git a/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromFilters.test.js b/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromFilters.test.js index bd659e8295..c153f85762 100644 --- a/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromFilters.test.js +++ b/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromFilters.test.js @@ -4,7 +4,7 @@ describe('HELPER PLUGIN | utils | generateSearchFromFilters', () => { it('should return a string with all the applied filters', () => { const data = { _limit: 10, - _sort: 'id:ASC', + sort: 'id:ASC', _page: 2, filters: [ { @@ -46,7 +46,7 @@ describe('HELPER PLUGIN | utils | generateSearchFromFilters', () => { }; const expected = - '_limit=10&_sort=id:ASC&_page=2&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; + '_limit=10&sort=id:ASC&_page=2&bool=true&big_number_ne=1&created_at_lt=2019-08-01T00:00:00Z&date_lte=2019-08-02T00:00:00Z&decimal_number_gt=2&enum_ne=noon&float_number_gte=3'; const encoded = expected .split('&') .map(pair => { diff --git a/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromObject.test.js b/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromObject.test.js index 419fe9c596..ff52224685 100644 --- a/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromObject.test.js +++ b/packages/core/helper-plugin/lib/src/utils/tests/generateSearchFromObject.test.js @@ -2,15 +2,15 @@ import generateSearchFromObject from '../generateSearchFromObject'; describe('HELPER PLUGIN | utils | generateSearchFromObject', () => { it('should return a string containing the _limit, _start and order', () => { - const search = { _page: 1, _limit: 10, _sort: 'city:ASC' }; - const expected = '_limit=10&_sort=city:ASC&_start=0'; + const search = { _page: 1, _limit: 10, sort: 'city:ASC' }; + const expected = '_limit=10&sort=city:ASC&_start=0'; expect(generateSearchFromObject(search)).toEqual(expected); }); it('should remove the _q param from the search if it is empty', () => { - const search = { _page: 1, _limit: 10, _sort: 'city:ASC', _q: '' }; - const expected = '_limit=10&_sort=city:ASC&_start=0'; + const search = { _page: 1, _limit: 10, sort: 'city:ASC', _q: '' }; + const expected = '_limit=10&sort=city:ASC&_start=0'; expect(generateSearchFromObject(search)).toEqual(expected); }); @@ -19,11 +19,11 @@ describe('HELPER PLUGIN | utils | generateSearchFromObject', () => { const search = { _page: 1, _limit: 10, - _sort: 'city:ASC', + sort: 'city:ASC', _q: '', filters: [], }; - const expected = '_limit=10&_sort=city:ASC&_start=0'; + const expected = '_limit=10&sort=city:ASC&_start=0'; expect(generateSearchFromObject(search)).toEqual(expected); }); @@ -33,11 +33,11 @@ describe('HELPER PLUGIN | utils | generateSearchFromObject', () => { _limit: 10, _page: 1, _q: '', - _sort: 'city:ASC', + sort: 'city:ASC', filters: [{ name: 'city', filter: '=', value: 'test' }], }; - const expected = '_limit=10&_sort=city:ASC&city=test&_start=0'; + const expected = '_limit=10&sort=city:ASC&city=test&_start=0'; expect(generateSearchFromObject(search)).toEqual(expected); }); diff --git a/packages/core/strapi/lib/middlewares/session/__tests__/session.test.js b/packages/core/strapi/lib/middlewares/session/__tests__/session.test.js index 8ed74eb124..08b1377f7a 100644 --- a/packages/core/strapi/lib/middlewares/session/__tests__/session.test.js +++ b/packages/core/strapi/lib/middlewares/session/__tests__/session.test.js @@ -2,7 +2,7 @@ const path = require('path'); const createMiddleware = require('../index'); -const configProvider = require('../../../core/base-providers/config-provider'); +const configProvider = require('../../../core/registries/config'); describe('Session middleware', () => { beforeEach(() => { diff --git a/packages/core/upload/admin/src/components/BrowseAssets/index.js b/packages/core/upload/admin/src/components/BrowseAssets/index.js index 719130307e..4bd2145a0c 100644 --- a/packages/core/upload/admin/src/components/BrowseAssets/index.js +++ b/packages/core/upload/admin/src/components/BrowseAssets/index.js @@ -134,7 +134,7 @@ const BrowseAssets = () => { /> )} - + { const ref = useRef(); - const dispatch = useDispatch(); ref.current = setPlugin; - const toggleNotification = useNotification(); + // TODO: remove useEffect(() => { - const getData = async () => { - const requestURL = '/content-manager/content-types'; - - try { - const { data } = await request(requestURL, { method: 'GET' }); - const fileModel = data.find(model => model.uid === 'plugin::upload.file'); - const timestamps = get(fileModel, ['options', 'timestamps']); - - dispatch(setFileModelTimestamps(timestamps)); - - ref.current(pluginId); - } catch (err) { - toggleNotification({ - type: 'warning', - message: { id: 'content-manager.error.model.fetch' }, - }); - } - }; - - getData(); - }, [dispatch, toggleNotification]); + ref.current(pluginId); + }, []); return null; }; diff --git a/packages/core/upload/admin/src/components/Initializer/reducer.js b/packages/core/upload/admin/src/components/Initializer/reducer.js index 7950b1d1d2..af85eeb6e2 100644 --- a/packages/core/upload/admin/src/components/Initializer/reducer.js +++ b/packages/core/upload/admin/src/components/Initializer/reducer.js @@ -2,7 +2,8 @@ import produce from 'immer'; import { SET_FILE_MODE_TIMESTAMPS } from './constants'; const initialState = { - fileModelTimestamps: [], + // TODO: rename to camelCase + fileModelTimestamps: ['created_at', 'updated_at'], }; const reducer = (state = initialState, action) => @@ -10,7 +11,7 @@ const reducer = (state = initialState, action) => produce(state, draftState => { switch (action.type) { case SET_FILE_MODE_TIMESTAMPS: { - draftState.fileModelTimestamps = action.timestamps; + // draftState.fileModelTimestamps = action.timestamps; break; } default: diff --git a/packages/core/upload/admin/src/components/InputModalStepperProvider/index.js b/packages/core/upload/admin/src/components/InputModalStepperProvider/index.js index d05e641890..08a698af44 100644 --- a/packages/core/upload/admin/src/components/InputModalStepperProvider/index.js +++ b/packages/core/upload/admin/src/components/InputModalStepperProvider/index.js @@ -64,7 +64,7 @@ const InputModalStepperProvider = ({ : [], params: { ...state.params, - _sort: `${updated_at}:DESC`, + sort: `${updated_at}:DESC`, }, }) ); @@ -336,7 +336,7 @@ const InputModalStepperProvider = ({ const fetchMediaLibFilesCount = async () => { const requestURL = getRequestUrl('files/count'); - const paramsToSend = getFilters(['_limit', '_sort', '_start']); + const paramsToSend = getFilters(['_limit', '_start']); try { return await request(`${requestURL}?${paramsToSend}`, { diff --git a/packages/core/upload/admin/src/components/InputModalStepperProvider/reducer.js b/packages/core/upload/admin/src/components/InputModalStepperProvider/reducer.js index 9563c64e55..e9e3ebb17d 100644 --- a/packages/core/upload/admin/src/components/InputModalStepperProvider/reducer.js +++ b/packages/core/upload/admin/src/components/InputModalStepperProvider/reducer.js @@ -21,7 +21,7 @@ const initialState = { _start: 0, _q: '', filters: [], - _sort: null, + sort: null, }, currentStep: 'list', isFormDisabled: false, @@ -180,7 +180,7 @@ const reducer = (state, action) => } case 'RESET_PROPS': { if (action.defaultSort) { - draftState.params._sort = action.defaultSort; + draftState.params.sort = action.defaultSort; } else { return initialState; } diff --git a/packages/core/upload/admin/src/components/InputModalStepperProvider/tests/reducer.test.js b/packages/core/upload/admin/src/components/InputModalStepperProvider/tests/reducer.test.js index 465208d897..e280d07ba3 100644 --- a/packages/core/upload/admin/src/components/InputModalStepperProvider/tests/reducer.test.js +++ b/packages/core/upload/admin/src/components/InputModalStepperProvider/tests/reducer.test.js @@ -1725,7 +1725,7 @@ describe('UPLOAD | components | InputModalStepperProvider | reducer', () => { _start: 0, _q: '', filters: [], - _sort: null, + sort: null, }, currentStep: 'list', isFormDisabled: false, diff --git a/packages/core/upload/admin/src/components/SortListItem/index.js b/packages/core/upload/admin/src/components/SortListItem/index.js index 48eb0ff821..9e3fe9147c 100644 --- a/packages/core/upload/admin/src/components/SortListItem/index.js +++ b/packages/core/upload/admin/src/components/SortListItem/index.js @@ -8,7 +8,7 @@ import IntlText from '../IntlText'; const SortListItem = ({ onClick, selectedItem, label, value }) => { const handleClick = () => { - onClick({ target: { name: '_sort', value } }); + onClick({ target: { name: 'sort', value } }); }; return ( diff --git a/packages/core/upload/admin/src/pages/HomePage/HomePageContent/HomePageSettings.js b/packages/core/upload/admin/src/pages/HomePage/HomePageContent/HomePageSettings.js index d32ae5f05a..c398fd9e7e 100644 --- a/packages/core/upload/admin/src/pages/HomePage/HomePageContent/HomePageSettings.js +++ b/packages/core/upload/admin/src/pages/HomePage/HomePageContent/HomePageSettings.js @@ -72,7 +72,7 @@ const HomePageSettings = ({ )} - + diff --git a/packages/core/upload/admin/src/pages/HomePage/index.js b/packages/core/upload/admin/src/pages/HomePage/index.js index d5641621e3..084570f825 100644 --- a/packages/core/upload/admin/src/pages/HomePage/index.js +++ b/packages/core/upload/admin/src/pages/HomePage/index.js @@ -42,7 +42,7 @@ const HomePage = () => { const isMounted = useRef(true); const pluginName = formatMessage({ id: getTrad('plugin.name') }); - const paramsKeys = ['_limit', '_start', '_q', '_sort']; + const paramsKeys = ['_limit', '_start', '_q', 'sort']; useEffect(() => { return () => (isMounted.current = false); @@ -74,9 +74,9 @@ const HomePage = () => { const dataRequestURL = getRequestUrl('files'); const params = generateStringFromParams(query); - const paramsToSend = params.includes('_sort') + const paramsToSend = params.includes('sort') ? params - : params.concat(`&_sort=${updated_at}:DESC`); + : params.concat(`&sort=${updated_at}:DESC`); try { const data = await request(`${dataRequestURL}?${paramsToSend}`, { @@ -98,7 +98,7 @@ const HomePage = () => { }; const fetchDataCount = async () => { - const params = generateStringFromParams(query, ['_limit', '_sort', '_start']); + const params = generateStringFromParams(query, ['_limit', '_start']); const requestURL = getRequestUrl('files/count'); try { diff --git a/packages/core/utils/lib/relations.js b/packages/core/utils/lib/relations.js index 1e6b3e213b..0eef9fefba 100644 --- a/packages/core/utils/lib/relations.js +++ b/packages/core/utils/lib/relations.js @@ -1,6 +1,6 @@ 'use strict'; -const MANY_RELATIONS = ['oneToMany', 'manyToMany', 'manyWay']; +const MANY_RELATIONS = ['oneToMany', 'manyToMany']; const getRelationalFields = contentType => { return Object.keys(contentType.attributes).filter(attributeName => { diff --git a/packages/generators/app/package.json b/packages/generators/app/package.json index c01fb89f51..270b68eae3 100644 --- a/packages/generators/app/package.json +++ b/packages/generators/app/package.json @@ -23,7 +23,7 @@ "node-fetch": "^2.6.1", "node-machine-id": "^1.1.10", "ora": "^5.4.0", - "tar": "6.1.2", + "tar": "6.1.4", "uuid": "^3.3.2" }, "scripts": { diff --git a/packages/plugins/graphql/services/__tests__/data-loaders.test.js b/packages/plugins/graphql/services/__tests__/data-loaders.test.js index 32e3f68677..63e7ac54e8 100644 --- a/packages/plugins/graphql/services/__tests__/data-loaders.test.js +++ b/packages/plugins/graphql/services/__tests__/data-loaders.test.js @@ -35,7 +35,7 @@ describe('dataloader', () => { test('makeQuery calls find', async () => { const uid = 'uid'; const find = jest.fn(() => [{ id: 1 }]); - const filters = { _limit: 5, _sort: 'field' }; + const filters = { limit: 5, sort: 'field' }; global.strapi = { query() { diff --git a/packages/plugins/i18n/admin/src/utils/tests/getInitialLocale.test.js b/packages/plugins/i18n/admin/src/utils/tests/getInitialLocale.test.js index 4ed11b9afc..bb5a7c8109 100644 --- a/packages/plugins/i18n/admin/src/utils/tests/getInitialLocale.test.js +++ b/packages/plugins/i18n/admin/src/utils/tests/getInitialLocale.test.js @@ -5,7 +5,7 @@ describe('getInitialLocale', () => { const query = { page: '1', pageSize: '10', - _sort: 'Name:ASC', + sort: 'Name:ASC', plugins: { i18n: { locale: 'fr-FR' }, }, @@ -47,7 +47,7 @@ describe('getInitialLocale', () => { const query = { page: '1', pageSize: '10', - _sort: 'Name:ASC', + sort: 'Name:ASC', plugins: { something: 'great', }, @@ -90,7 +90,7 @@ describe('getInitialLocale', () => { const query = { page: '1', pageSize: '10', - _sort: 'Name:ASC', + sort: 'Name:ASC', plugins: { something: 'great', }, diff --git a/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js b/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js index fc357f9d43..5bffb7dd19 100644 --- a/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js +++ b/packages/plugins/i18n/tests/content-manager/list-relation.test.e2e.js @@ -81,6 +81,12 @@ describe('i18n - Relation-list route', () => { beforeAll(async () => { await builder .addContentTypes([productModel, shopModel]) + .addFixtures('plugin::i18n.locale', [ + { + name: 'It', + code: 'it', + }, + ]) .addFixtures(shopModel.name, shops) .addFixtures(productModel.name, products) .build(); diff --git a/test/helpers/builder/index.js b/test/helpers/builder/index.js index cc08be9f4c..3ecc772a85 100644 --- a/test/helpers/builder/index.js +++ b/test/helpers/builder/index.js @@ -26,7 +26,7 @@ const createTestBuilder = (options = {}) => { }, sanitizedFixturesFor(modelName, strapi) { - const model = strapi.getModel(`application::${modelName}.${modelName}`); + const model = strapi.getModel(modelsUtils.toUID(modelName)); const fixtures = this.fixturesFor(modelName); return sanitizeEntity(fixtures, { model }); diff --git a/test/helpers/models.js b/test/helpers/models.js index 5a8c527495..70622273d8 100644 --- a/test/helpers/models.js +++ b/test/helpers/models.js @@ -3,6 +3,10 @@ const { isFunction, isNil, prop } = require('lodash/fp'); const { createStrapiInstance } = require('./strapi'); +const toUID = name => { + return name.includes('::') ? name : `application::${name}.${name}`; +}; + const createHelpers = async ({ strapi: strapiInstance = null, ...options } = {}) => { const strapi = strapiInstance || (await createStrapiInstance(options)); const contentTypeService = strapi.plugins['content-type-builder'].services['content-types']; @@ -141,7 +145,7 @@ async function createFixtures(dataMap, { strapi: strapiIst } = {}) { const entries = []; for (const data of dataMap[model]) { - entries.push(await strapi.query(`application::${model}.${model}`).create({ data })); + entries.push(await strapi.entityService.create(toUID(model), { data })); } resultMap[model] = entries; @@ -158,9 +162,7 @@ async function createFixturesFor(model, entries, { strapi: strapiIst } = {}) { for (const entry of entries) { const dataToCreate = isFunction(entry) ? entry(results) : entry; - results.push( - await strapi.query(`application::${model}.${model}`).create({ data: dataToCreate }) - ); + results.push(await strapi.entityService.create(toUID(model), { data: dataToCreate })); } await cleanup(); @@ -171,9 +173,7 @@ async function createFixturesFor(model, entries, { strapi: strapiIst } = {}) { async function deleteFixturesFor(model, entries, { strapi: strapiIst } = {}) { const { strapi, cleanup } = await createHelpers({ strapi: strapiIst }); - await strapi - .query(`application::${model}.${model}`) - .delete({ where: { id: entries.map(prop('id')) } }); + await strapi.query(toUID(model)).deleteMany({ where: { id: entries.map(prop('id')) } }); await cleanup(); } @@ -185,7 +185,7 @@ async function modifyContentType(data, { strapi } = {}) { delete sanitizedData.editable; delete sanitizedData.restrictRelationsTo; - const uid = `application::${sanitizedData.name}.${sanitizedData.name}`; + const uid = toUID(sanitizedData.name); const ct = await contentTypeService.editContentType(uid, { contentType: { @@ -201,7 +201,7 @@ async function modifyContentType(data, { strapi } = {}) { async function getContentTypeSchema(modelName, { strapi: strapiIst } = {}) { const { strapi, contentTypeService, cleanup } = await createHelpers({ strapi: strapiIst }); - const uid = `application::${modelName}.${modelName}`; + const uid = toUID(modelName); const ct = contentTypeService.formatContentType(strapi.contentTypes[uid]); await cleanup(); @@ -210,6 +210,7 @@ async function getContentTypeSchema(modelName, { strapi: strapiIst } = {}) { } module.exports = { + toUID, // Create Content-Types createContentType, createContentTypes, diff --git a/yarn.lock b/yarn.lock index 43dacb0e7c..6a7d4d2e21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20172,10 +20172,10 @@ tar-stream@^2.0.1, tar-stream@^2.1.0, tar-stream@^2.1.4, tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.2.tgz#1f045a90a6eb23557a603595f41a16c57d47adc6" - integrity sha512-EwKEgqJ7nJoS+s8QfLYVGMDmAsj+StbI2AM/RTHeUSsOw6Z8bwNBRv5z3CY0m7laC5qUAqruLX5AhMuc5deY3Q== +tar@6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.4.tgz#9f0722b772a5e00dba7d52e1923b37a7ec3799b3" + integrity sha512-kcPWrO8S5ABjuZ/v1xQHP8xCEvj1dQ1d9iAb6Qs4jLYzaAIYWwST2IQpz7Ud8VNYRI+fGhFjrnzRKmRggKWg3g== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0"