Compare commits

...

11 Commits

Author SHA1 Message Date
Baptiste Studer
0adf3f0bda docs: Add json v2 in export formats 2024-01-05 15:24:03 +01:00
Baptiste Studer
da0a5d3633 chore(release): 1.23.1 2023-12-27 14:50:54 +01:00
Baptiste Studer
1af484f42b admin: Fix imports from design system package 2023-12-27 14:50:07 +01:00
Baptiste Studer
ee7fc354f4 chore(release): 1.23.0 2023-12-23 17:55:54 +01:00
Baptiste Studer
fac3dc668d
Merge pull request #163 from HighError/add-uk-locale
feat: 🎸 Added uk locale
2023-12-23 17:55:09 +01:00
HighError
00495915d5 feat: 🎸 Added uk locale 2023-12-22 11:39:35 +02:00
Baptiste Studer
f48341931d chore(release): 1.22.2 2023-12-09 14:41:23 +01:00
Baptiste Studer
cc8a3283bc chore(settings): Match latest vscode version 2023-12-09 14:41:01 +01:00
Baptiste Studer
de2383ec5b test(jest): Update globals 2023-12-09 14:40:23 +01:00
Baptiste Studer
131294b875 feat(import-v2): Import media of components 2023-12-09 14:40:01 +01:00
Baptiste Studer
02133210cc tests(import): Split media download 2023-12-09 14:07:07 +01:00
18 changed files with 156 additions and 53 deletions

View File

@ -1,7 +1,7 @@
{ {
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": true "source.fixAll.eslint": "explicit"
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"sqltools.connections": [ "sqltools.connections": [

View File

@ -2,6 +2,32 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [1.23.1](https://github.com/Baboo7/strapi-plugin-import-export-entries/compare/v1.23.0...v1.23.1) (2023-12-27)
## [1.23.0](https://github.com/Baboo7/strapi-plugin-import-export-entries/compare/v1.22.2...v1.23.0) (2023-12-23)
### ⚡️ Features
* 🎸 Added uk locale ([0049591](https://github.com/Baboo7/strapi-plugin-import-export-entries/commits/00495915d50281901b87f1ebe07c8e51b4b6a24c))
### [1.22.2](https://github.com/Baboo7/strapi-plugin-import-export-entries/compare/v1.22.1...v1.22.2) (2023-12-09)
### ⚡️ Features
* **import-v2:** Import media of components ([131294b](https://github.com/Baboo7/strapi-plugin-import-export-entries/commits/131294b875d4788055e92f9c95af757bfa7c0106))
### 🧪 Tests
* **jest:** Update globals ([de2383e](https://github.com/Baboo7/strapi-plugin-import-export-entries/commits/de2383ec5bd3340485fa68bfe9372424ec99bab4))
### 🧹 Chores
* **settings:** Match latest vscode version ([cc8a328](https://github.com/Baboo7/strapi-plugin-import-export-entries/commits/cc8a3283bc8597bb84c90fbffb13b8a967637c97))
### [1.22.1](https://github.com/Baboo7/strapi-plugin-import-export-entries/compare/v1.22.0...v1.22.1) (2023-11-30) ### [1.22.1](https://github.com/Baboo7/strapi-plugin-import-export-entries/compare/v1.22.0...v1.22.1) (2023-11-30)

View File

@ -448,9 +448,10 @@ await service.exportData(
/** /**
* Export format. * Export format.
* - csv * - csv
* - json: javascript object notation * - json
* - json-v2: json in the new json file format (see section `Importing Data`)
*/ */
exportFormat: "csv" | "json"; exportFormat: "csv" | "json" | "json-v2";
/** Search query used to select the entries to export. The package `qs` is used to parse the query. */ /** Search query used to select the entries to export. The package `qs` is used to parse the query. */
search?: string; search?: string;
/** Whether to apply the search query. */ /** Whether to apply the search query. */

View File

@ -1,4 +1,4 @@
import { Button } from '@strapi/design-system/Button'; import { Button } from '@strapi/design-system';
import { CheckPermissions } from '@strapi/helper-plugin'; import { CheckPermissions } from '@strapi/helper-plugin';
import Download from '@strapi/icons/Download'; import Download from '@strapi/icons/Download';
import React, { useState } from 'react'; import React, { useState } from 'react';

View File

@ -1,14 +1,6 @@
import './style.css'; import './style.css';
import { Button } from '@strapi/design-system/Button'; import { Button, Checkbox, Flex, Grid, GridItem, Loader, ModalBody, ModalFooter, ModalHeader, ModalLayout, Option, Portal, Select, Typography } from '@strapi/design-system';
import { Checkbox } from '@strapi/design-system/Checkbox';
import { Flex } from '@strapi/design-system/Flex';
import { Grid, GridItem } from '@strapi/design-system/Grid';
import { Loader } from '@strapi/design-system/Loader';
import { ModalBody, ModalFooter, ModalHeader, ModalLayout } from '@strapi/design-system/ModalLayout';
import { Portal } from '@strapi/design-system/Portal';
import { Option, Select } from '@strapi/design-system/Select';
import { Typography } from '@strapi/design-system/Typography';
import pick from 'lodash/pick'; import pick from 'lodash/pick';
import range from 'lodash/range'; import range from 'lodash/range';
import qs from 'qs'; import qs from 'qs';

View File

@ -1,5 +1,4 @@
import { Box } from '@strapi/design-system/Box'; import { BaseHeaderLayout, Box } from '@strapi/design-system';
import { BaseHeaderLayout } from '@strapi/design-system/Layout';
import React from 'react'; import React from 'react';
import { useI18n } from '../../hooks/useI18n'; import { useI18n } from '../../hooks/useI18n';

View File

@ -1,4 +1,4 @@
import { Button } from '@strapi/design-system/Button'; import { Button } from '@strapi/design-system';
import { CheckPermissions } from '@strapi/helper-plugin'; import { CheckPermissions } from '@strapi/helper-plugin';
import Upload from '@strapi/icons/Upload'; import Upload from '@strapi/icons/Upload';
import React, { useState } from 'react'; import React, { useState } from 'react';

View File

@ -1,13 +1,6 @@
import './style.css'; import './style.css';
import { Button } from '@strapi/design-system/Button'; import { Button, EmptyStateLayout, Flex, Icon, Loader, ModalBody, ModalFooter, ModalHeader, ModalLayout, Portal, Typography } from '@strapi/design-system';
import { EmptyStateLayout } from '@strapi/design-system/EmptyStateLayout';
import { Flex } from '@strapi/design-system/Flex';
import { Icon } from '@strapi/design-system/Icon';
import { Loader } from '@strapi/design-system/Loader';
import { ModalBody, ModalFooter, ModalHeader, ModalLayout } from '@strapi/design-system/ModalLayout';
import { Portal } from '@strapi/design-system/Portal';
import { Typography } from '@strapi/design-system/Typography';
import CheckCircle from '@strapi/icons/CheckCircle'; import CheckCircle from '@strapi/icons/CheckCircle';
import IconCode from '@strapi/icons/Code'; import IconCode from '@strapi/icons/Code';
import IconFile from '@strapi/icons/File'; import IconFile from '@strapi/icons/File';

View File

@ -1,7 +1,4 @@
import { Box } from '@strapi/design-system/Box'; import { Box, Option, Select, Tab, TabGroup, TabPanel, TabPanels, Tabs, Typography } from '@strapi/design-system';
import { Option, Select } from '@strapi/design-system/Select';
import { Tab, TabGroup, TabPanel, TabPanels, Tabs } from '@strapi/design-system/Tabs';
import { Typography } from '@strapi/design-system/Typography';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { api } from '../../../../api'; import { api } from '../../../../api';

View File

@ -1,7 +1,6 @@
import './style.css'; import './style.css';
import { Alert } from '@strapi/design-system/Alert'; import { Alert, Portal } from '@strapi/design-system';
import { Portal } from '@strapi/design-system/Portal';
import React from 'react'; import React from 'react';
import { useAlerts } from '../../../hooks/useAlerts'; import { useAlerts } from '../../../hooks/useAlerts';

View File

@ -1,7 +1,4 @@
import { Box } from '@strapi/design-system/Box'; import { Box, Divider, Flex, Typography } from '@strapi/design-system';
import { Divider } from '@strapi/design-system/Divider';
import { Flex } from '@strapi/design-system/Flex';
import { Typography } from '@strapi/design-system/Typography';
import { CheckPermissions } from '@strapi/helper-plugin'; import { CheckPermissions } from '@strapi/helper-plugin';
import React from 'react'; import React from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';

View File

@ -1,10 +1,4 @@
import { Box } from '@strapi/design-system/Box'; import { Box, Checkbox, ContentLayout, Flex, Link, Option, Select, Typography } from '@strapi/design-system';
import { Checkbox } from '@strapi/design-system/Checkbox';
import { Flex } from '@strapi/design-system/Flex';
import { ContentLayout } from '@strapi/design-system/Layout';
import { Link } from '@strapi/design-system/Link';
import { Option, Select } from '@strapi/design-system/Select';
import { Typography } from '@strapi/design-system/Typography';
import { CheckPagePermissions } from '@strapi/helper-plugin'; import { CheckPagePermissions } from '@strapi/helper-plugin';
import range from 'lodash/range'; import range from 'lodash/range';
import React, { memo, useState } from 'react'; import React, { memo, useState } from 'react';

View File

@ -0,0 +1,58 @@
{
"plugin.name": "Import Export",
"plugin.description": "Імпорт/експорт даних лише кількома кліками",
"plugin.cta.back-to-data-sources": "Назад до джерел даних",
"plugin.cta.back-to-options": "Назад до параметрів",
"plugin.cta.cancel": "Скасувати",
"plugin.cta.close": "Закрити",
"plugin.cta.copy-to-clipboard": "Копіювати в буфер обміну",
"plugin.cta.download-file": "Завантажити файл",
"plugin.cta.get-data": "Отримати дані",
"plugin.cta.export": "Експорт",
"plugin.cta.import": "Імпорт",
"plugin.data-format.csv": "CSV [не підтримується]",
"plugin.data-format.json": "JSON [застаріле]",
"plugin.data-format.json-v2": "JSON (версія 2)",
"plugin.form.field.id-field.hint": "Виберіть поле, яке використовується як унікальний ідентифікатор",
"plugin.form.field.id-field.label": "Поле ідентифікатора",
"plugin.page.homepage.section.quick-actions.title": "Швидкі дії",
"plugin.page.homepage.section.preferences.title": "Уподобання",
"plugin.page.homepage.section.need-help.title": "Запит функції/звіт про помилку",
"plugin.page.homepage.section.need-help.description": "Не соромтеся переглянути нашу дорожньою карту продукту, або зв'язати з нами за допомогою Discord або github ✌️",
"plugin.page.homepage.section.need-help.discord": "Discord",
"plugin.page.homepage.section.need-help.github": "GitHub",
"plugin.page.homepage.section.need-help.product-roadmap": "Дорожня карта продукту",
"plugin.message.export.error.forbidden.title": "Заборонено",
"plugin.message.export.error.forbidden.message": "Ви не маєте дозволу читати цей тип даних.",
"plugin.message.export.error.unexpected.title": "Помилка експорту",
"plugin.message.export.error.unexpected.message": "Під час експорту ваших даних сталася неочікувана помилка.",
"plugin.message.import.error.forbidden.title": "Заборонено",
"plugin.message.import.error.forbidden.message": "Ви не маєте дозволу на запис цього типу даних.",
"plugin.message.import.error.payload-too-large.title": "Корисне навантаження занадто велике",
"plugin.message.import.error.payload-too-large.message": "Розмір даних перевищує обмеження розміру файлу на сервері. ",
"plugin.message.import.error.unexpected.title": "Помилка імпорту",
"plugin.message.import.error.unexpected.message": "Під час імпорту ваших даних сталася неочікувана помилка.",
"plugin.message.import.success.imported-successfully": "Ваші дані успішно імпортовано.",
"plugin.message.import.success.imported.title": "Імпорт успішний",
"plugin.message.import.success.imported.message": "Ваші дані успішно імпортовано.",
"plugin.message.import.error.imported-partial.title": "Частково не вдалося імпортувати",
"plugin.message.import.error.imported-partial.message": "Деякі дані не вдалося імпортувати. ",
"plugin.import.data-source-step.title": "Виберіть джерело даних",
"plugin.import.drag-drop-file": "Перетягнути",
"plugin.import.file-name": "Ім'я файлу",
"plugin.import.importing-data": "Імпорт даних...",
"plugin.import.partially-failed": "Частково не вдалося імпортувати",
"plugin.import.detailed-information": "Детальна інформація:",
"plugin.import.use-code-editor": "Використовуйте редактор коду",
"plugin.import.tab.file": "Файл",
"plugin.import.tab.options": "Опції",
"plugin.export.copied": "Скопійовано",
"plugin.export.fetching-data": "Отримання даних...",
"plugin.export.export-format": "Формат експорту",
"plugin.export.options": "Опції",
"plugin.export.plugins-content-types": "Експортувати типи вмісту плагінів",
"plugin.export.relations-as-id": "Експорт відносин як id.",
"plugin.export.apply-filters-and-sort": "Застосуйте фільтри та сортуйте експортовані дані.",
"plugin.export.deepness": "Глибина",
"plugin.export.whole-database": "Вся база даних"
}

View File

@ -10,9 +10,7 @@ module.exports = {
testTimeout: 30_000, testTimeout: 30_000,
verbose: true, verbose: true,
globals: { globals: {
'ts-jest': { strapi: true,
strapi: true,
},
}, },
transform: { transform: {
'^.+\\.tsx?$': [ '^.+\\.tsx?$': [

View File

@ -1,6 +1,6 @@
{ {
"name": "strapi-plugin-import-export-entries", "name": "strapi-plugin-import-export-entries",
"version": "1.22.1", "version": "1.23.1",
"description": "Import/Export data from and to your database in just few clicks.", "description": "Import/Export data from and to your database in just few clicks.",
"strapi": { "strapi": {
"name": "import-export-entries", "name": "import-export-entries",

View File

@ -7,7 +7,7 @@ import { extract, toArray } from '../../../libs/arrays';
import { ObjectBuilder } from '../../../libs/objects'; import { ObjectBuilder } from '../../../libs/objects';
import { getModel, getModelAttributes, isComponentAttribute, isDynamicZoneAttribute, isMediaAttribute, isRelationAttribute } from '../../utils/models'; import { getModel, getModelAttributes, isComponentAttribute, isDynamicZoneAttribute, isMediaAttribute, isRelationAttribute } from '../../utils/models';
import { Entry, EntryId, Schema, SchemaUID, User } from '../../types'; import { Entry, EntryId, Schema, SchemaUID, User } from '../../types';
import { toPairs } from 'lodash'; import { head, toPairs } from 'lodash';
import { FileEntry, FileEntryDynamicZone, FileId } from './types'; import { FileEntry, FileEntryDynamicZone, FileId } from './types';
import { findOrImportFile } from './utils/file'; import { findOrImportFile } from './utils/file';
@ -365,6 +365,12 @@ function getComponentData(
} else { } else {
store[attributeName] = fileIdToDbId.getMapping(attribute.target, attributeValue as number | string); store[attributeName] = fileIdToDbId.getMapping(attribute.target, attributeValue as number | string);
} }
} else if (isMediaAttribute(attribute)) {
if (attribute.multiple) {
store[attributeName] = castArray(attributeValue as number | string | (number | string)[]).map((id) => fileIdToDbId.getMapping('plugin::upload.file', id));
} else {
store[attributeName] = fileIdToDbId.getMapping('plugin::upload.file', `${head(castArray(attributeValue as number | string))}`);
}
} }
} }

View File

@ -64,6 +64,14 @@
"2": { "2": {
"id": 2, "id": 2,
"url": "https://storage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerBlazes.jpg" "url": "https://storage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerBlazes.jpg"
},
"3": {
"id": 3,
"url": "https://storage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerJoyrides.jpg"
},
"4": {
"id": 4,
"url": "https://storage.googleapis.com/gtv-videos-bucket/sample/images/TearsOfSteel.jpg"
} }
}, },
"shared.utensil": { "shared.utensil": {
@ -71,12 +79,14 @@
"id": 1, "id": 1,
"name": "Fork", "name": "Fork",
"description": "Really useful", "description": "Really useful",
"picture": 3,
"made_by": 1 "made_by": 1
}, },
"2": { "2": {
"id": 2, "id": 2,
"name": "Knife", "name": "Knife",
"description": "Be careful kiddo", "description": "Be careful kiddo",
"picture": 4,
"made_by": 2 "made_by": 2
} }
} }

View File

@ -561,7 +561,6 @@ describe('import service', () => {
expect(entries[0].name).toBe('Dubillot Brasserie'); expect(entries[0].name).toBe('Dubillot Brasserie');
expect(entries[0].locale).toBe('en'); expect(entries[0].locale).toBe('en');
expect(entries[0].description).toBe('Awesome restaurant'); expect(entries[0].description).toBe('Awesome restaurant');
expect(entries[0].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
expect(entries[0].owned_by.name).toBe('Charles'); expect(entries[0].owned_by.name).toBe('Charles');
expect(entries[0].utensils.length).toBe(2); expect(entries[0].utensils.length).toBe(2);
expect(entries[0].utensils[0].name).toBe('Fork'); expect(entries[0].utensils[0].name).toBe('Fork');
@ -575,7 +574,6 @@ describe('import service', () => {
expect(entries[1].name).toBe('Martin Brasserie'); expect(entries[1].name).toBe('Martin Brasserie');
expect(entries[1].locale).toBe('en'); expect(entries[1].locale).toBe('en');
expect(entries[1].description).toBe('Checkout the chicken'); expect(entries[1].description).toBe('Checkout the chicken');
expect(entries[1].logo.name).toBe('gtv-videos-bucket-sample-images-ForBiggerBlazes.jpg');
expect(entries[1].owned_by.name).toBe('Victor'); expect(entries[1].owned_by.name).toBe('Victor');
expect(entries[1].utensils.length).toBe(1); expect(entries[1].utensils.length).toBe(1);
expect(entries[1].utensils[0].name).toBe('Fork'); expect(entries[1].utensils[0].name).toBe('Fork');
@ -583,7 +581,6 @@ describe('import service', () => {
expect(entries[2].name).toBe('Brasserie Dubillot'); expect(entries[2].name).toBe('Brasserie Dubillot');
expect(entries[2].locale).toBe('fr'); expect(entries[2].locale).toBe('fr');
expect(entries[2].description).toBe('Incroyable restaurant'); expect(entries[2].description).toBe('Incroyable restaurant');
expect(entries[0].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
expect(entries[2].owned_by.name).toBe('Charles'); expect(entries[2].owned_by.name).toBe('Charles');
expect(entries[2].utensils.length).toBe(2); expect(entries[2].utensils.length).toBe(2);
expect(entries[2].utensils[0].name).toBe('Fork'); expect(entries[2].utensils[0].name).toBe('Fork');
@ -595,6 +592,38 @@ describe('import service', () => {
expect(entries[2].localizations[0].locale).toBe('en'); expect(entries[2].localizations[0].locale).toBe('en');
}); });
it('should download media when import file', async () => {
await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} });
let entries = await strapi.db.query('api::restaurant.restaurant').findMany({
populate: {
logo: true,
},
} as any);
expect(entries[0].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
expect(entries[1].logo.name).toBe('gtv-videos-bucket-sample-images-ForBiggerBlazes.jpg');
expect(entries[0].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
});
it('should download media of component when import file', async () => {
await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} });
let entries = await strapi.db.query('api::restaurant.restaurant').findMany({
populate: {
utensils: {
populate: true,
},
},
} as any);
expect(entries[0].utensils[0].picture.name).toBe('gtv-videos-bucket-sample-images-ForBiggerJoyrides.jpg');
expect(entries[0].utensils[1].picture.name).toBe('gtv-videos-bucket-sample-images-TearsOfSteel.jpg');
expect(entries[2].utensils[0].picture.name).toBe('gtv-videos-bucket-sample-images-ForBiggerJoyrides.jpg');
expect(entries[2].utensils[0].picture.name).toBe('gtv-videos-bucket-sample-images-ForBiggerJoyrides.jpg');
expect(entries[2].utensils[1].picture.name).toBe('gtv-videos-bucket-sample-images-TearsOfSteel.jpg');
});
it('should be idempotent when import same file multiple times', async () => { it('should be idempotent when import same file multiple times', async () => {
// 1st import. // 1st import.
await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} }); await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} });
@ -617,7 +646,6 @@ describe('import service', () => {
expect(entries[0].name).toBe('Dubillot Brasserie'); expect(entries[0].name).toBe('Dubillot Brasserie');
expect(entries[0].locale).toBe('en'); expect(entries[0].locale).toBe('en');
expect(entries[0].description).toBe('Awesome restaurant'); expect(entries[0].description).toBe('Awesome restaurant');
expect(entries[0].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
expect(entries[0].owned_by.name).toBe('Charles'); expect(entries[0].owned_by.name).toBe('Charles');
expect(entries[0].utensils.length).toBe(2); expect(entries[0].utensils.length).toBe(2);
expect(entries[0].utensils[0].name).toBe('Fork'); expect(entries[0].utensils[0].name).toBe('Fork');
@ -631,7 +659,6 @@ describe('import service', () => {
expect(entries[1].name).toBe('Martin Brasserie'); expect(entries[1].name).toBe('Martin Brasserie');
expect(entries[1].locale).toBe('en'); expect(entries[1].locale).toBe('en');
expect(entries[1].description).toBe('Checkout the chicken'); expect(entries[1].description).toBe('Checkout the chicken');
expect(entries[1].logo.name).toBe('gtv-videos-bucket-sample-images-ForBiggerBlazes.jpg');
expect(entries[1].owned_by.name).toBe('Victor'); expect(entries[1].owned_by.name).toBe('Victor');
expect(entries[1].utensils.length).toBe(1); expect(entries[1].utensils.length).toBe(1);
expect(entries[1].utensils[0].name).toBe('Fork'); expect(entries[1].utensils[0].name).toBe('Fork');
@ -639,7 +666,6 @@ describe('import service', () => {
expect(entries[2].name).toBe('Brasserie Dubillot'); expect(entries[2].name).toBe('Brasserie Dubillot');
expect(entries[2].locale).toBe('fr'); expect(entries[2].locale).toBe('fr');
expect(entries[2].description).toBe('Incroyable restaurant'); expect(entries[2].description).toBe('Incroyable restaurant');
expect(entries[2].logo.name).toBe('gtv-videos-bucket-sample-images-BigBuckBunny.jpg');
expect(entries[2].owned_by.name).toBe('Charles'); expect(entries[2].owned_by.name).toBe('Charles');
expect(entries[2].utensils.length).toBe(2); expect(entries[2].utensils.length).toBe(2);
expect(entries[2].utensils[0].name).toBe('Fork'); expect(entries[2].utensils[0].name).toBe('Fork');
@ -649,9 +675,16 @@ describe('import service', () => {
expect(entries[2].localizations.length).toBe(1); expect(entries[2].localizations.length).toBe(1);
expect(entries[2].localizations[0].name).toBe('Dubillot Brasserie'); expect(entries[2].localizations[0].name).toBe('Dubillot Brasserie');
expect(entries[2].localizations[0].locale).toBe('en'); expect(entries[2].localizations[0].locale).toBe('en');
});
it('should download media only once when import same file multiple times', async () => {
// 1st import.
await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} });
// 2nd import.
await getService('import').importDataV2(dataCreate, { slug: 'custom:db', user: {} });
const fileEntries = await strapi.db.query('plugin::upload.file').findMany({}); const fileEntries = await strapi.db.query('plugin::upload.file').findMany({});
expect(fileEntries.length).toBe(2); expect(fileEntries.length).toBe(4);
}); });
it('should update entries when import file', async () => { it('should update entries when import file', async () => {