From 4dcfe4ab407307ff7c7b5e37fad783c28e31df54 Mon Sep 17 00:00:00 2001 From: Convly Date: Fri, 4 Nov 2022 15:06:36 +0100 Subject: [PATCH 1/9] (tmp) init morph populate --- .../lib/query/helpers/populate/apply.js | 19 +++++++++-- .../core/utils/lib/convert-query-params.js | 33 +++++++++---------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/packages/core/database/lib/query/helpers/populate/apply.js b/packages/core/database/lib/query/helpers/populate/apply.js index 2ae346d135..130f2aa093 100644 --- a/packages/core/database/lib/query/helpers/populate/apply.js +++ b/packages/core/database/lib/query/helpers/populate/apply.js @@ -470,6 +470,8 @@ const morphToMany = async (input, ctx) => { }, {}); const map = {}; + const { on, ...typePopulate } = populateValue; + for (const type of Object.keys(idsByType)) { const ids = idsByType[type]; @@ -480,10 +482,14 @@ const morphToMany = async (input, ctx) => { continue; } + if (on && on[type]) { + Object.assign(typePopulate, on[type]); + } + const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(populateValue) + .init(typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); @@ -579,7 +585,16 @@ const morphToOne = async (input, ctx) => { // TODO: Omit limit & offset to avoid needing a query per result to avoid making too many queries const pickPopulateParams = (populate) => { - const fieldsToPick = ['select', 'count', 'where', 'populate', 'orderBy', 'filters', 'ordering']; + const fieldsToPick = [ + 'select', + 'count', + 'where', + 'populate', + 'orderBy', + 'filters', + 'ordering', + 'on', + ]; if (populate.count !== true) { fieldsToPick.push('limit', 'offset'); diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index 38d1af385b..4c11510375 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -6,17 +6,17 @@ * Converts the standard Strapi REST query params to a more usable format for querying * You can read more here: https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#filters */ + const { + isNil, + toNumber, + isInteger, has, isEmpty, isObject, isPlainObject, cloneDeep, get, - mergeAll, - isNil, - toNumber, - isInteger, } = require('lodash/fp'); const _ = require('lodash'); const parseType = require('./parse-type'); @@ -185,22 +185,19 @@ const convertPopulateObject = (populate, schema) => { return acc; } - // FIXME: This is a temporary solution for dynamic zones that should be - // fixed when we'll implement a more accurate way to query them - if (attribute.type === 'dynamiczone') { - const populates = attribute.components - .map((uid) => strapi.getModel(uid)) - .map((schema) => convertNestedPopulate(subPopulate, schema)) - .map((populate) => (populate === true ? {} : populate)) // cast boolean to empty object to avoid merging issues - .filter((populate) => populate !== false); - - if (isEmpty(populates)) { - return acc; - } - + if (subPopulate && subPopulate.on) { return { ...acc, - [key]: mergeAll(populates), + [key]: { + ...subPopulate, + on: Object.entries(subPopulate.on).reduce( + (newTypeSubPopulate, [type, typeSubPopulate]) => ({ + ...newTypeSubPopulate, + [type]: convertNestedPopulate(typeSubPopulate, strapi.getModel(type)), + }), + {} + ), + }, }; } From 8c2fb155b82e747b4ea2b63424589c213fb81e1c Mon Sep 17 00:00:00 2001 From: Convly Date: Tue, 15 Nov 2022 15:14:28 +0100 Subject: [PATCH 2/9] hanlde morphToOne populate & re-add legacy way of querying DZs --- .../lib/query/helpers/populate/apply.js | 15 ++++++----- .../core/utils/lib/convert-query-params.js | 27 ++++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/packages/core/database/lib/query/helpers/populate/apply.js b/packages/core/database/lib/query/helpers/populate/apply.js index 130f2aa093..1138bab261 100644 --- a/packages/core/database/lib/query/helpers/populate/apply.js +++ b/packages/core/database/lib/query/helpers/populate/apply.js @@ -446,6 +446,11 @@ const morphToMany = async (input, ctx) => { .where({ [joinColumn.name]: referencedValues, ...(joinTable.on || {}), + // If the populateValue contains an "on" property, + // only populate the types defined in it + ...('on' in populateValue + ? { [morphColumn.typeColumn.name]: Object.keys(populateValue.on) } + : {}), }) .orderBy([joinColumn.name, 'order']) .execute({ mapResults: false }); @@ -482,14 +487,10 @@ const morphToMany = async (input, ctx) => { continue; } - if (on && on[type]) { - Object.assign(typePopulate, on[type]); - } - const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(typePopulate) + .init(on && type in on ? on[type] : typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); @@ -546,6 +547,8 @@ const morphToOne = async (input, ctx) => { }, {}); const map = {}; + const { on, ...typePopulate } = populateValue; + for (const type of Object.keys(idsByType)) { const ids = idsByType[type]; @@ -558,7 +561,7 @@ const morphToOne = async (input, ctx) => { const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(populateValue) + .init(on && type in on ? on[type] : typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index 4c11510375..a6b6cadb26 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -17,6 +17,7 @@ const { isPlainObject, cloneDeep, get, + mergeAll, } = require('lodash/fp'); const _ = require('lodash'); const parseType = require('./parse-type'); @@ -185,14 +186,13 @@ const convertPopulateObject = (populate, schema) => { return acc; } - if (subPopulate && subPopulate.on) { + if (subPopulate && 'on' in subPopulate) { return { ...acc, [key]: { - ...subPopulate, on: Object.entries(subPopulate.on).reduce( - (newTypeSubPopulate, [type, typeSubPopulate]) => ({ - ...newTypeSubPopulate, + (acc, [type, typeSubPopulate]) => ({ + ...acc, [type]: convertNestedPopulate(typeSubPopulate, strapi.getModel(type)), }), {} @@ -201,6 +201,25 @@ const convertPopulateObject = (populate, schema) => { }; } + // TODO: Deprecated way of handling dynamic zone populate queries. It's kept as is, + // as removing it could break existing user queries but should be removed in V5. + if (attribute.type === 'dynamiczone') { + const populates = attribute.components + .map((uid) => strapi.getModel(uid)) + .map((schema) => convertNestedPopulate(subPopulate, schema)) + .map((populate) => (populate === true ? {} : populate)) // cast boolean to empty object to avoid merging issues + .filter((populate) => populate !== false); + + if (isEmpty(populates)) { + return acc; + } + + return { + ...acc, + [key]: mergeAll(populates), + }; + } + // NOTE: Retrieve the target schema UID. // Only handles basic relations, medias and component since it's not possible // to populate with options for a dynamic zone or a polymorphic relation From 0c205d0f58537a52bf0b4d77f89798731a8dee48 Mon Sep 17 00:00:00 2001 From: Convly Date: Tue, 15 Nov 2022 18:31:33 +0100 Subject: [PATCH 3/9] Fix convert query params for 'true' subPopulate --- packages/core/utils/lib/convert-query-params.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index a6b6cadb26..cd274b97d7 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -186,7 +186,7 @@ const convertPopulateObject = (populate, schema) => { return acc; } - if (subPopulate && 'on' in subPopulate) { + if (typeof subPopulate === 'object' && 'on' in subPopulate) { return { ...acc, [key]: { From 7c1837bbe1daaa2a62bad41a59c3968b0a9e6cd6 Mon Sep 17 00:00:00 2001 From: Convly Date: Mon, 21 Nov 2022 11:02:38 +0100 Subject: [PATCH 4/9] Add test + update logic --- .../lib/query/helpers/populate/apply.js | 4 +- .../api/populate/filtering/index.test.api.js | 60 +++++++++++++++++++ .../core/utils/lib/convert-query-params.js | 14 ++++- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/packages/core/database/lib/query/helpers/populate/apply.js b/packages/core/database/lib/query/helpers/populate/apply.js index 1138bab261..fee3feeeaa 100644 --- a/packages/core/database/lib/query/helpers/populate/apply.js +++ b/packages/core/database/lib/query/helpers/populate/apply.js @@ -490,7 +490,7 @@ const morphToMany = async (input, ctx) => { const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(on && type in on ? on[type] : typePopulate) + .init(on?.[type] ?? typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); @@ -561,7 +561,7 @@ const morphToOne = async (input, ctx) => { const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(on && type in on ? on[type] : typePopulate) + .init(on?.[type] ?? typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); diff --git a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js index 24931e882f..44c39d34e7 100644 --- a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js +++ b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js @@ -315,4 +315,64 @@ describe('Populate filters', () => { expect(body.data[0].attributes.third).toBeUndefined(); }); }); + + describe('Populate a dynamic zone', () => { + test('Populate every components in the dynamic zone', async () => { + const qs = { + populate: { + dz: '*', + }, + }; + + const { status, body } = await rq.get(`/${schemas.contentTypes.b.pluralName}`, { qs }); + + expect(status).toBe(200); + expect(body.data).toHaveLength(2); + expect(body.data[0].attributes.dz).toHaveLength(3); + expect(body.data[1].attributes.dz).toHaveLength(1); + }); + + test('Populate only one component type using fragment', async () => { + const qs = { + populate: { + dz: { + on: { + 'default.foo': true, + }, + }, + }, + }; + + const { status, body } = await rq.get(`/${schemas.contentTypes.b.pluralName}`, { qs }); + + expect(status).toBe(200); + expect(body.data).toHaveLength(2); + expect(body.data[0].attributes.dz).toHaveLength(2); + expect(body.data[1].attributes.dz).toHaveLength(0); + }); + + test('Populate the dynamic zone with filters in fragments', async () => { + const qs = { + populate: { + dz: { + on: { + 'default.foo': { + filters: { number: { $lt: 2 } }, + }, + 'default.bar': { + filters: { title: { $contains: 'another' } }, + }, + }, + }, + }, + }; + + const { status, body } = await rq.get(`/${schemas.contentTypes.b.pluralName}`, { qs }); + + expect(status).toBe(200); + expect(body.data).toHaveLength(2); + expect(body.data[0].attributes.dz).toHaveLength(1); + expect(body.data[1].attributes.dz).toHaveLength(1); + }); + }); }); diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index cd274b97d7..182a1ff8bd 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -186,7 +186,15 @@ const convertPopulateObject = (populate, schema) => { return acc; } - if (typeof subPopulate === 'object' && 'on' in subPopulate) { + // Allow adding a 'on' strategy to populate queries for polymorphic relations, media and dynamic zones + const isAllowedAttributeForFragmentPopulate = + attribute.type === 'dynamiczone' || + attribute.type === 'media' || + (attribute.relation && attribute.relation.startsWith('morphTo')); + + const hasFragmentPopulateDefined = typeof subPopulate === 'object' && 'on' in subPopulate; + + if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined) { return { ...acc, [key]: { @@ -201,8 +209,8 @@ const convertPopulateObject = (populate, schema) => { }; } - // TODO: Deprecated way of handling dynamic zone populate queries. It's kept as is, - // as removing it could break existing user queries but should be removed in V5. + // TODO: This is a query's populate fallback for DynamicZone and is kept for legacy purpose. + // Removing it could break existing user queries but it should be removed in V5. if (attribute.type === 'dynamiczone') { const populates = attribute.components .map((uid) => strapi.getModel(uid)) From b784135413e9b5adee7b24e6d9bba5398939b415 Mon Sep 17 00:00:00 2001 From: Convly Date: Mon, 21 Nov 2022 14:20:59 +0100 Subject: [PATCH 5/9] Fix typo --- .../core/strapi/tests/api/populate/filtering/index.test.api.js | 2 +- packages/core/utils/lib/convert-query-params.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js index 44c39d34e7..f0c5103df9 100644 --- a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js +++ b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js @@ -317,7 +317,7 @@ describe('Populate filters', () => { }); describe('Populate a dynamic zone', () => { - test('Populate every components in the dynamic zone', async () => { + test('Populate every component in the dynamic zone', async () => { const qs = { populate: { dz: '*', diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index 182a1ff8bd..ec77ca23ce 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -186,7 +186,7 @@ const convertPopulateObject = (populate, schema) => { return acc; } - // Allow adding a 'on' strategy to populate queries for polymorphic relations, media and dynamic zones + // Allow adding an 'on' strategy to populate queries for polymorphic relations, media and dynamic zones const isAllowedAttributeForFragmentPopulate = attribute.type === 'dynamiczone' || attribute.type === 'media' || From c49df55a6780bf60f3fc8c7344240454398d7148 Mon Sep 17 00:00:00 2001 From: Convly Date: Tue, 22 Nov 2022 11:40:37 +0100 Subject: [PATCH 6/9] Update tests & add type util to convert query params --- .../api/populate/filtering/index.test.api.js | 51 +++++++++++++++++-- packages/core/utils/lib/content-types.js | 16 ++++-- .../core/utils/lib/convert-query-params.js | 11 ++-- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js index f0c5103df9..279bedddb3 100644 --- a/packages/core/strapi/tests/api/populate/filtering/index.test.api.js +++ b/packages/core/strapi/tests/api/populate/filtering/index.test.api.js @@ -108,6 +108,11 @@ const fixtures = { number: 2, field: 'short string', }, + { + __component: 'default.foo', + number: 3, + field: 'long string', + }, { __component: 'default.bar', title: 'this is a title', @@ -328,8 +333,19 @@ describe('Populate filters', () => { expect(status).toBe(200); expect(body.data).toHaveLength(2); - expect(body.data[0].attributes.dz).toHaveLength(3); - expect(body.data[1].attributes.dz).toHaveLength(1); + + fixtures.b.forEach((fixture, i) => { + const res = body.data[i]; + const { dz } = res.attributes; + + expect(dz).toHaveLength(fixture.dz.length); + expect(dz).toMatchObject( + fixture.dz.map((component) => ({ + ...omit('field', component), + id: expect.any(Number), + })) + ); + }); }); test('Populate only one component type using fragment', async () => { @@ -347,8 +363,18 @@ describe('Populate filters', () => { expect(status).toBe(200); expect(body.data).toHaveLength(2); - expect(body.data[0].attributes.dz).toHaveLength(2); + + expect(body.data[0].attributes.dz).toHaveLength(3); expect(body.data[1].attributes.dz).toHaveLength(0); + + const expected = fixtures.b[0].dz + .filter(({ __component }) => __component === 'default.foo') + .map((component) => ({ + ...component, + id: expect.any(Number), + })); + + expect(body.data[0].attributes.dz).toMatchObject(expected); }); test('Populate the dynamic zone with filters in fragments', async () => { @@ -357,7 +383,7 @@ describe('Populate filters', () => { dz: { on: { 'default.foo': { - filters: { number: { $lt: 2 } }, + filters: { number: { $lt: 3 } }, }, 'default.bar': { filters: { title: { $contains: 'another' } }, @@ -371,8 +397,23 @@ describe('Populate filters', () => { expect(status).toBe(200); expect(body.data).toHaveLength(2); - expect(body.data[0].attributes.dz).toHaveLength(1); + expect(body.data[0].attributes.dz).toHaveLength(2); expect(body.data[1].attributes.dz).toHaveLength(1); + + const filter = (data = []) => + data + .filter(({ __component, number, title }) => { + if (__component === 'default.foo') return number < 3; + if (__component === 'default.bar') return title.includes('another'); + return false; + }) + .map((component) => ({ + ...(component.__component === 'default.foo' ? component : omit('field', component)), + id: expect.any(Number), + })); + + expect(body.data[0].attributes.dz).toMatchObject(filter(fixtures.b[0].dz)); + expect(body.data[1].attributes.dz).toMatchObject(filter(fixtures.b[1].dz)); }); }); }); diff --git a/packages/core/utils/lib/content-types.js b/packages/core/utils/lib/content-types.js index cec115eab4..0303b8d2a5 100644 --- a/packages/core/utils/lib/content-types.js +++ b/packages/core/utils/lib/content-types.js @@ -104,12 +104,16 @@ const isPrivateAttribute = (model = {}, attributeName) => { }; const isScalarAttribute = (attribute) => { - return !['media', 'component', 'relation', 'dynamiczone'].includes(attribute.type); + return !['media', 'component', 'relation', 'dynamiczone'].includes(attribute?.type); +}; +const isMediaAttribute = (attribute) => attribute?.type === 'media'; +const isRelationalAttribute = (attribute) => attribute?.type === 'relation'; +const isComponentAttribute = (attribute) => ['component', 'dynamiczone'].includes(attribute?.type); + +const isDynamicZoneAttribute = (attribute) => attribute?.type === 'dynamiczone'; +const isMorphToRelationalAttribute = (attribute) => { + return isRelationalAttribute(attribute) && attribute?.relation?.startsWith?.('morphTo'); }; -const isMediaAttribute = (attribute) => attribute && attribute.type === 'media'; -const isRelationalAttribute = (attribute) => attribute && attribute.type === 'relation'; -const isComponentAttribute = (attribute) => - attribute && ['component', 'dynamiczone'].includes(attribute.type); const getComponentAttributes = (schema) => { return _.reduce( @@ -158,6 +162,8 @@ module.exports = { isMediaAttribute, isRelationalAttribute, isComponentAttribute, + isDynamicZoneAttribute, + isMorphToRelationalAttribute, isTypedAttribute, getPrivateAttributes, isPrivateAttribute, diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index ec77ca23ce..3dea86ee7b 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -23,6 +23,11 @@ const _ = require('lodash'); const parseType = require('./parse-type'); const contentTypesUtils = require('./content-types'); const { PaginationError } = require('./errors'); +const { + isMediaAttribute, + isDynamicZoneAttribute, + isMorphToRelationalAttribute, +} = require('./content-types'); const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants; @@ -188,9 +193,9 @@ const convertPopulateObject = (populate, schema) => { // Allow adding an 'on' strategy to populate queries for polymorphic relations, media and dynamic zones const isAllowedAttributeForFragmentPopulate = - attribute.type === 'dynamiczone' || - attribute.type === 'media' || - (attribute.relation && attribute.relation.startsWith('morphTo')); + isDynamicZoneAttribute(attribute) || + isMediaAttribute(attribute) || + isMorphToRelationalAttribute(attribute); const hasFragmentPopulateDefined = typeof subPopulate === 'object' && 'on' in subPopulate; From 19eb79535af5e8dc9d4e95083175c4729b44203c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20No=C3=ABl?= Date: Sat, 26 Nov 2022 11:48:20 +0100 Subject: [PATCH 7/9] replace mysql by bitnami/mysql image --- .github/workflows/contributor-doc.yml | 2 +- .github/workflows/nightly.yml | 2 +- .github/workflows/tests.yml | 43 +++++++++++++-------------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/.github/workflows/contributor-doc.yml b/.github/workflows/contributor-doc.yml index f0f191db13..7cabdfc7b7 100644 --- a/.github/workflows/contributor-doc.yml +++ b/.github/workflows/contributor-doc.yml @@ -21,7 +21,7 @@ permissions: {} jobs: deploy: permissions: - contents: write # to push pages branch (peaceiris/actions-gh-pages) + contents: write # to push pages branch (peaceiris/actions-gh-pages) environment: name: github-pages diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9944e2f659..a71b1edf88 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: permissions: - contents: read # to fetch code (actions/checkout) + contents: read # to fetch code (actions/checkout) jobs: publish: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f3028a49ce..497d804e64 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ concurrency: cancel-in-progress: true permissions: - contents: read # to fetch code (actions/checkout) + contents: read # to fetch code (actions/checkout) jobs: lint: @@ -142,18 +142,18 @@ jobs: node: [14, 16, 18] services: mysql: - image: mysql + image: bitnami/mysql:latest + env: + MYSQL_ROOT_PASSWORD: strapi + MYSQL_USER: strapi + MYSQL_PASSWORD: strapi + MYSQL_DATABASE: strapi_test + MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password options: >- --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - -e MYSQL_ROOT_PASSWORD=strapi - -e MYSQL_ROOT_HOST="%" - -e MYSQL_USER=strapi - -e MYSQL_PASSWORD=strapi - -e MYSQL_DATABASE=strapi_test - --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" ports: # Maps tcp port 5432 on service container to the host - 3306:3306 @@ -180,18 +180,17 @@ jobs: node: [14, 16, 18] services: mysql: - image: mysql:5 + image: bitnami/mysql:5.7 + env: + MYSQL_ROOT_PASSWORD: strapi + MYSQL_USER: strapi + MYSQL_PASSWORD: strapi + MYSQL_DATABASE: strapi_test options: >- --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - -e MYSQL_ROOT_PASSWORD=strapi - -e MYSQL_ROOT_HOST="%" - -e MYSQL_USER=strapi - -e MYSQL_PASSWORD=strapi - -e MYSQL_DATABASE=strapi_test - --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" ports: # Maps tcp port 5432 on service container to the host - 3306:3306 @@ -288,18 +287,18 @@ jobs: node: [14, 16, 18] services: mysql: - image: mysql + image: bitnami/mysql:latest + env: + MYSQL_ROOT_PASSWORD: strapi + MYSQL_USER: strapi + MYSQL_PASSWORD: strapi + MYSQL_DATABASE: strapi_test + MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password options: >- --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - -e MYSQL_ROOT_PASSWORD=strapi - -e MYSQL_ROOT_HOST="%" - -e MYSQL_USER=strapi - -e MYSQL_PASSWORD=strapi - -e MYSQL_DATABASE=strapi_test - --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" ports: # Maps tcp port 5432 on service container to the host - 3306:3306 From 78b83190707b5818d67e77bfd24c9e87c70291ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20No=C3=ABl?= Date: Mon, 28 Nov 2022 10:45:30 +0100 Subject: [PATCH 8/9] remove unecessary checks in tests breaking with mysql 5 --- .../graphql-upload-automatic-folder.test.api.js | 4 ---- .../tests/content-api/upload-automatic-folder.test.api.js | 8 -------- 2 files changed, 12 deletions(-) diff --git a/packages/core/upload/tests/content-api/graphql-upload-automatic-folder.test.api.js b/packages/core/upload/tests/content-api/graphql-upload-automatic-folder.test.api.js index 0f107196fd..ac45b18316 100644 --- a/packages/core/upload/tests/content-api/graphql-upload-automatic-folder.test.api.js +++ b/packages/core/upload/tests/content-api/graphql-upload-automatic-folder.test.api.js @@ -115,7 +115,6 @@ describe('Uploads folder (GraphQL)', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -170,7 +169,6 @@ describe('Uploads folder (GraphQL)', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -255,7 +253,6 @@ describe('Uploads folder (GraphQL)', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -310,7 +307,6 @@ describe('Uploads folder (GraphQL)', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); diff --git a/packages/core/upload/tests/content-api/upload-automatic-folder.test.api.js b/packages/core/upload/tests/content-api/upload-automatic-folder.test.api.js index 2e5fd8a76e..8e837ab82e 100644 --- a/packages/core/upload/tests/content-api/upload-automatic-folder.test.api.js +++ b/packages/core/upload/tests/content-api/upload-automatic-folder.test.api.js @@ -118,7 +118,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -163,7 +162,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -230,7 +228,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -276,7 +273,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -360,7 +356,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -408,7 +403,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); uploadFolder = file.folder; }); @@ -563,7 +557,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); }); expect(files.every((file) => file.folder.id === files[0].folder.id)).toBe(true); @@ -625,7 +618,6 @@ describe('Uploads folder', () => { }, folderPath: `/${file.folder.pathId}`, }); - expect(file.folder.id).not.toBe(uploadFolder.id); }); expect(files.every((file) => file.folder.id === files[0].folder.id)).toBe(true); From 5d9faf38611634995f7d2c733c61088f1a862e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20No=C3=ABl?= Date: Tue, 29 Nov 2022 14:02:44 +0100 Subject: [PATCH 9/9] fix test - array's order --- .../core/admin/server/tests/admin-api-token-crud.test.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/admin/server/tests/admin-api-token-crud.test.api.js b/packages/core/admin/server/tests/admin-api-token-crud.test.api.js index 7e1122252a..ae030617d5 100644 --- a/packages/core/admin/server/tests/admin-api-token-crud.test.api.js +++ b/packages/core/admin/server/tests/admin-api-token-crud.test.api.js @@ -436,7 +436,7 @@ describe('Admin API Token v2 CRUD (api)', () => { expect(res.body.data).toMatchObject({ accessKey: expect.any(String), name: body.name, - permissions: body.permissions, + permissions: expect.arrayContaining(body.permissions), description: body.description, type: body.type, id: expect.any(Number),