Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,17 @@ export class DataTypeApiHelper {
return await this.save(dataType);
}

async createTiptapDataTypeWithMediaFolder(name: string, mediaFolderId: string) {
await this.ensureNameNotExists(name);

const dataType = new TiptapDataTypeBuilder()
.withName(name)
.withMediaFolderParentId(mediaFolderId)
.build();

return await this.save(dataType);
}

async createTipTapDataTypeWithABlock(name: string, contentElementTypeKey: string) {
await this.ensureNameNotExists(name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ export class DataTypeUiHelper extends UiBaseLocators {
}

async addMediaStartNode(mediaName: string) {
await this.click(this.mediaCardItems.filter({hasText: mediaName}));
await this.selectMediaWithName(mediaName);
await this.clickChooseModalButton();
}

Expand Down Expand Up @@ -733,6 +733,11 @@ export class DataTypeUiHelper extends UiBaseLocators {
await this.clickChooseModalButton();
}

async removeImageUploadFolder(mediaFolderName: string) {
await this.click(this.page.locator(`uui-card-media[name="${mediaFolderName}"]`).locator('[label="Remove"]'));
await this.click(this.confirmToRemoveBtn);
}

async clickAddWithPlusButton() {
await this.click(this.addWithPlusBtn);
}
Expand Down
17 changes: 10 additions & 7 deletions tests/Umbraco.Tests.AcceptanceTest/lib/helpers/UiBaseLocators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1236,18 +1236,16 @@ export class UiBaseLocators extends BasePage {
await this.click(this.mediaCardItems.filter({hasText: name}));
}

async selectMediaWithName(mediaName: string, isForce: boolean = false) {
async selectMediaWithName(mediaName: string) {
const mediaLocator = this.mediaCardItems.filter({hasText: mediaName});
await this.waitForVisible(mediaLocator);
// Using direct click with position option (not supported by BasePage.click)
await mediaLocator.click({position: {x: 0.5, y: 0.5}, force: isForce});
await this.click(mediaLocator.locator('#select-checkbox'), {force: true});
}

async selectMediaWithTestId(mediaKey: string) {
const locator = this.page.getByTestId('media:' + mediaKey);
await this.waitForVisible(locator);
// Using direct click with position option (not supported by BasePage.click)
await locator.click({position: {x: 0.5, y: 0.5}});
const mediaLocator = this.page.getByTestId('media:' + mediaKey);
await this.waitForVisible(mediaLocator);
await this.click(mediaLocator.locator('#select-checkbox'), {force: true});
}

async clickMediaPickerModalSubmitButton() {
Expand Down Expand Up @@ -1620,4 +1618,9 @@ export class UiBaseLocators extends BasePage {
await this.pressKey(this.searchTxt, 'Enter');
await this.page.waitForTimeout(ConstantHelper.wait.medium);
}

async isSelectCheckboxVisibleForMediaName(mediaName: string, isVisible: boolean = true) {
const selectCheckboxLocator = this.mediaCardItems.filter({hasText: mediaName}).locator('#select-checkbox');
await this.isVisible(selectCheckboxLocator, isVisible);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ test('can create content with the media link', async ({umbracoApi, umbracoUi}) =
await umbracoUi.content.goToContentWithName(contentName);
await umbracoUi.content.clickAddMultiURLPickerButton();
await umbracoUi.content.clickMediaLinkButton();
await umbracoUi.content.selectMediaWithName(mediaFileName, true);
await umbracoUi.content.selectMediaWithName(mediaFileName);
await umbracoUi.content.clickChooseModalButton();
await umbracoUi.content.clickLinkPickerAddButton();
await umbracoUi.content.clickSaveButtonAndWaitForContentToBeUpdated();
Expand Down Expand Up @@ -178,7 +178,7 @@ test('can add multiple links in the content', {tag: '@release'}, async ({umbraco
// Add media link
await umbracoUi.content.clickAddMultiURLPickerButton();
await umbracoUi.content.clickMediaLinkButton();
await umbracoUi.content.selectMediaWithName(mediaFileName, true);
await umbracoUi.content.selectMediaWithName(mediaFileName);
await umbracoUi.content.clickChooseModalButton();
await umbracoUi.content.clickLinkPickerAddButton();
await umbracoUi.waitForTimeout(500); // Wait for the media link to be added
Expand Down Expand Up @@ -388,6 +388,62 @@ test('can create content with target toggle enabled to open link in new window',
expect(contentData.values[0].value[0].target).toEqual('_blank');
});

test('cannot select a media folder as a media link', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => {
// Arrange
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
const mediaFolderName = 'TestMediaFolder';
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
await umbracoUi.goToBackOffice();
await umbracoUi.content.goToSection(ConstantHelper.sections.content);

// Act
await umbracoUi.content.goToContentWithName(contentName);
await umbracoUi.content.clickAddMultiURLPickerButton();
await umbracoUi.content.clickMediaLinkButton();

// Assert
await umbracoUi.content.isSelectCheckboxVisibleForMediaName(mediaFolderName, false);

// Clean
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
});

test('can select a media file inside a folder as a media link', async ({umbracoApi, umbracoUi}) => {
// Arrange
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
const mediaFolderName = 'TestMediaFolder';
const mediaFileName = 'TestMediaFileInFolder';
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
await umbracoApi.media.ensureNameNotExists(mediaFileName);
const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
const mediaFileId = await umbracoApi.media.createDefaultMediaWithImageAndParentId(mediaFileName, mediaFolderId);
await umbracoUi.goToBackOffice();
await umbracoUi.content.goToSection(ConstantHelper.sections.content);

// Act
await umbracoUi.content.goToContentWithName(contentName);
await umbracoUi.content.clickAddMultiURLPickerButton();
await umbracoUi.content.clickMediaLinkButton();
await umbracoUi.content.clickMediaWithName(mediaFolderName);
await umbracoUi.content.selectMediaWithName(mediaFileName);
await umbracoUi.content.clickChooseModalButton();
await umbracoUi.content.clickLinkPickerAddButton();
await umbracoUi.content.clickSaveButtonAndWaitForContentToBeUpdated();

// Assert
const contentData = await umbracoApi.document.getByName(contentName);
expect(contentData.values[0].alias).toEqual(AliasHelper.toAlias(dataTypeName));
expect(contentData.values[0].value.length).toBe(1);
expect(contentData.values[0].value[0].type).toEqual('media');
expect(contentData.values[0].value[0].unique).toEqual(mediaFileId);
expect(contentData.values[0].value[0].name).toEqual(mediaFileName);

// Clean
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
await umbracoApi.media.ensureNameNotExists(mediaFileName);
});

test.describe('manual tab validation tests', () => {
test('cannot create content with empty manual url and anchor', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AliasHelper, ConstantHelper, test} from '@umbraco/acceptance-test-helpers';

Check notice on line 1 in tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/MediaPicker.spec.ts

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

✅ Getting better: Code Duplication

reduced similar code in: 'can add start node','can remove start node'. Avoid duplicated, aka copy-pasted, code inside the module. More duplication lowers the code health.
import {expect} from "@playwright/test";

const mediaPickerTypes = [
Expand Down Expand Up @@ -127,46 +127,85 @@
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'filter', mediaTypeData.id)).toBeFalsy();
});

test('can add start node', async ({umbracoApi, umbracoUi}) => {
test('cannot add a media file as start node', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => {
// Arrange
// Create media
const mediaName = 'TestStartNode';
const mediaId = await umbracoApi.media.createDefaultMediaWithArticle(mediaName);
const mediaName = 'TestStartNodeFile';
await umbracoApi.media.createDefaultMediaWithArticle(mediaName);
expect(await umbracoApi.media.doesNameExist(mediaName)).toBeTruthy();
await umbracoApi.dataType.createDefaultMediaPickerDataType(customDataTypeName);
await umbracoUi.dataType.goToDataType(customDataTypeName);

// Act
await umbracoUi.dataType.clickChooseStartNodeButton();
await umbracoUi.dataType.addMediaStartNode(mediaName);
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'startNodeId', mediaId)).toBeTruthy();
await umbracoUi.dataType.isMediaCardItemWithNameDisabled(mediaName);

// Clean
await umbracoApi.media.ensureNameNotExists(mediaName);
});

test('can remove start node', async ({umbracoApi, umbracoUi}) => {
test('can add a media folder as start node', async ({umbracoApi, umbracoUi}) => {
// Arrange
// Create media
const mediaName = 'TestStartNode';
await umbracoApi.media.ensureNameNotExists(mediaName);
const mediaId = await umbracoApi.media.createDefaultMediaWithArticle(mediaName);
expect(await umbracoApi.media.doesNameExist(mediaName)).toBeTruthy();
await umbracoApi.dataType.createImageMediaPickerDataTypeWithStartNodeId(customDataTypeName, mediaId);
const mediaFolderName = 'TestStartNodeFolder';
const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
await umbracoApi.dataType.createDefaultMediaPickerDataType(customDataTypeName);
await umbracoUi.dataType.goToDataType(customDataTypeName);

// Act
await umbracoUi.dataType.removeMediaStartNode(mediaName);
await umbracoUi.dataType.clickChooseStartNodeButton();
await umbracoUi.dataType.selectMediaWithName(mediaFolderName);
await umbracoUi.dataType.clickChooseModalButton();
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'startNodeId', mediaId)).toBeFalsy();
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'startNodeId', mediaFolderId)).toBeTruthy();

// Clean
await umbracoApi.media.ensureNameNotExists(mediaName);
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
});

test('can remove a media folder start node', async ({umbracoApi, umbracoUi}) => {
// Arrange
const mediaFolderName = 'TestStartNodeFolder';
const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
await umbracoApi.dataType.createMediaPickerDataTypeWithStartNodeId(customDataTypeName, mediaFolderId);
await umbracoUi.dataType.goToDataType(customDataTypeName);

// Act
await umbracoUi.dataType.removeMediaStartNode(mediaFolderName);
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'startNodeId', mediaFolderId)).toBeFalsy();

// Clean
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
});

test('can add a nested media folder as start node', async ({umbracoApi, umbracoUi}) => {
// Arrange
const parentFolderName = 'ParentMediaFolder';
const childFolderName = 'ChildMediaFolder';
await umbracoApi.media.ensureNameNotExists(parentFolderName);
const parentFolderId = await umbracoApi.media.createDefaultMediaFolder(parentFolderName);
const childFolderId = await umbracoApi.media.createDefaultMediaFolderAndParentId(childFolderName, parentFolderId);
await umbracoApi.dataType.createDefaultMediaPickerDataType(customDataTypeName);
await umbracoUi.dataType.goToDataType(customDataTypeName);

// Act
await umbracoUi.dataType.clickChooseStartNodeButton();
await umbracoUi.dataType.clickMediaWithName(parentFolderName);
await umbracoUi.dataType.selectMediaWithName(childFolderName);
await umbracoUi.dataType.clickChooseModalButton();
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(customDataTypeName, 'startNodeId', childFolderId)).toBeTruthy();

// Clean
await umbracoApi.media.ensureNameNotExists(parentFolderName);
});

for (const mediaPicker of mediaPickerTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ test('can add an available block', async ({umbracoApi, umbracoUi}) => {
await umbracoApi.documentType.ensureNameNotExists(elementTypeName);
});

test('can add image upload folder', async ({umbracoApi, umbracoUi}) => {
test('can add image upload folder', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => {
// Arrange
const mediaFolderName = 'TestMediaFolder';
const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
Expand All @@ -147,6 +147,88 @@ test('can add image upload folder', async ({umbracoApi, umbracoUi}) => {
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
});

test('cannot select a media file as image upload folder', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => {
// Arrange
const mediaFileName = 'TestMediaFile';
await umbracoApi.media.createDefaultMediaFile(mediaFileName);
await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName);
await umbracoUi.dataType.goToDataType(tipTapName);

// Act
await umbracoUi.dataType.clickChooseWithPlusButton();

// Assert
await umbracoUi.dataType.isMediaCardItemWithNameDisabled(mediaFileName);
await umbracoUi.dataType.isSelectCheckboxVisibleForMediaName(mediaFileName, false);

// Clean
await umbracoApi.media.ensureNameNotExists(mediaFileName);
});

test('can remove image upload folder', async ({umbracoApi, umbracoUi}) => {
// Arrange
const mediaFolderName = 'TestMediaFolder';
const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName);
await umbracoApi.dataType.createTiptapDataTypeWithMediaFolder(tipTapName, mediaFolderId);
await umbracoUi.dataType.goToDataType(tipTapName);

// Act
await umbracoUi.dataType.removeImageUploadFolder(mediaFolderName);
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(tipTapName, 'mediaParentId', mediaFolderId)).toBeFalsy();

// Clean
await umbracoApi.media.ensureNameNotExists(mediaFolderName);
});

test('can update image upload folder', async ({umbracoApi, umbracoUi}) => {
// Arrange
const firstFolderName = 'FirstMediaFolder';
const secondFolderName = 'SecondMediaFolder';
const firstFolderId = await umbracoApi.media.createDefaultMediaFolder(firstFolderName);
const secondFolderId = await umbracoApi.media.createDefaultMediaFolder(secondFolderName);
await umbracoApi.dataType.createTiptapDataTypeWithMediaFolder(tipTapName, firstFolderId);
await umbracoUi.dataType.goToDataType(tipTapName);

// Act
await umbracoUi.dataType.removeImageUploadFolder(firstFolderName);
await umbracoUi.dataType.addImageUploadFolder(secondFolderName);
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(tipTapName, 'mediaParentId', secondFolderId)).toBeTruthy();
expect(await umbracoApi.dataType.doesDataTypeHaveValue(tipTapName, 'mediaParentId', firstFolderId)).toBeFalsy();

// Clean
await umbracoApi.media.ensureNameNotExists(firstFolderName);
await umbracoApi.media.ensureNameNotExists(secondFolderName);
});

test('can add a nested media folder as image upload folder', async ({umbracoApi, umbracoUi}) => {
// Arrange
const parentFolderName = 'ParentMediaFolder';
const childFolderName = 'ChildMediaFolder';
const parentFolderId = await umbracoApi.media.createDefaultMediaFolder(parentFolderName);
const childFolderId = await umbracoApi.media.createDefaultMediaFolderAndParentId(childFolderName, parentFolderId);
await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName);
await umbracoUi.dataType.goToDataType(tipTapName);

// Act
await umbracoUi.dataType.clickChooseWithPlusButton();
await umbracoUi.dataType.clickMediaWithName(parentFolderName);
await umbracoUi.dataType.selectMediaWithName(childFolderName);
await umbracoUi.dataType.clickChooseModalButton();
await umbracoUi.dataType.clickSaveButtonAndWaitForDataTypeToBeUpdated();

// Assert
expect(await umbracoApi.dataType.doesDataTypeHaveValue(tipTapName, 'mediaParentId', childFolderId)).toBeTruthy();

// Clean
await umbracoApi.media.ensureNameNotExists(parentFolderName);
});

test('can enable ignore user start nodes', async ({umbracoApi, umbracoUi}) => {
// Arrange
await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName);
Expand Down
Loading
Loading