Skip to content
This repository has been archived by the owner on May 8, 2024. It is now read-only.

Commit

Permalink
image tests start
Browse files Browse the repository at this point in the history
  • Loading branch information
Gebov committed Dec 19, 2023
1 parent 04d3ff7 commit b4413c3
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 98 deletions.
8 changes: 6 additions & 2 deletions src/nextjs-framework/editor/widget-framework/attributes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

import { Dictionary } from '../../typings/dictionary';
import { LinkModel } from './link-model';
import { WidgetContext } from './widget-context';

Expand All @@ -7,7 +8,7 @@ export type CustomAttribute = {
Value: string;
};

export function htmlAttributes(widgetContext: WidgetContext<any>, error: string | undefined = undefined) {
export function htmlAttributes(widgetContext: WidgetContext<any>, error: string | undefined = undefined): { [key: string]: any } {
if (!widgetContext.requestContext.isEdit) {
return {};
}
Expand Down Expand Up @@ -41,7 +42,10 @@ export function htmlAttributes(widgetContext: WidgetContext<any>, error: string
attributes['data-sfisemptyvisualhidden'] = false;
attributes['data-sfisempty'] = false;
attributes['draggable'] = true;
attributes['data-sfhasquickeditoperation'] = true;

if (widgetContext.metadata.editorMetadata?.HasQuickEditOperation) {
attributes['data-sfhasquickeditoperation'] = true;
}

if (error) {
attributes['data-sferror'] = error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export interface EditorMetadata {
Toolbox?: string;
Warning?: string;
HideEmptyVisual?: boolean;
HasQuickEditOperation?: boolean;
Order?: number;
}
78 changes: 39 additions & 39 deletions src/nextjs-framework/widgets/image/image-tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,53 @@ import { getCustomAttributes, classNames } from '../../editor';

const imageWrapperClass = 'd-inline-block';

export function ImageTag(props: {imageModel: ImageViewModel, className?: string }) {
export function ImageTag(props: { imageModel: ImageViewModel, className?: string }) {
const { imageModel, className = '', ...others } = props;
const selectedImageUrl = imageModel.SelectedImageUrl;
const imageCustomAttributes = getCustomAttributes(imageModel.Attributes, 'Image');
const altAttr = imageModel.AlternativeText;
const sortedList = (imageModel.Thumbnails || []).sort(t => t.Width);
const wrapperClass = classNames(imageWrapperClass, className);
const imageClass = classNames(className, {
[className]: className && imageModel.ImageSize === ImageDisplayMode.Responsive,
'img-fluid': imageModel.FitToContainer || true
});
[className]: className && imageModel.ImageSize === ImageDisplayMode.Responsive,
'img-fluid': !!imageModel.FitToContainer
});
return (
imageModel.ImageSize === ImageDisplayMode.Responsive
? <picture
{...others}
className={wrapperClass}>
{
sortedList.map((thumbnail: any, idx: number) => {
const sourceWidth = imageModel.Width && thumbnail.Width !== imageModel.Width ? thumbnail.Width : undefined;
const sourceHeight = imageModel.Height && thumbnail.Height !== imageModel.Height ? thumbnail.Height : undefined;
if (sourceWidth && sourceHeight) {
return (<source key={idx} media={`(max-width: ${thumbnail.Width}px)`}
srcSet={thumbnail.Url} type={thumbnail.MimeType}
width={sourceWidth}
height={sourceHeight}
/>);
? <picture
{...others}
className={wrapperClass}>
{
sortedList.map((thumbnail: any, idx: number) => {
const sourceWidth = imageModel.Width && thumbnail.Width !== imageModel.Width ? thumbnail.Width : undefined;
const sourceHeight = imageModel.Height && thumbnail.Height !== imageModel.Height ? thumbnail.Height : undefined;
if (sourceWidth && sourceHeight) {
return (<source key={idx} media={`(max-width: ${thumbnail.Width}px)`}
srcSet={thumbnail.Url} type={thumbnail.MimeType}
width={sourceWidth}
height={sourceHeight}
/>);
}
})
}
})
}
{
/* eslint-disable-next-line @next/next/no-img-element */
<img
{...imageCustomAttributes}
loading="lazy" className={imageClass}
src={selectedImageUrl} title={imageModel.Title} alt={altAttr} />}
</picture>
: <span {...others}>{
{
/* eslint-disable-next-line @next/next/no-img-element */
<img
{...imageCustomAttributes}
width={imageModel.ImageSize === ImageDisplayMode.CustomSize && imageModel.Width ? imageModel.Width : undefined}
height={imageModel.ImageSize === ImageDisplayMode.CustomSize && imageModel.Height ? imageModel.Height : undefined}
loading="lazy"
className={imageClass}
src={selectedImageUrl}
title={imageModel.Title}
alt={altAttr}/>
}
</span>);
}
<img
{...imageCustomAttributes}
loading="lazy" className={imageClass}
src={selectedImageUrl} title={imageModel.Title} alt={altAttr} />}
</picture>
: <span {...others}>{
/* eslint-disable-next-line @next/next/no-img-element */
<img
{...imageCustomAttributes}
width={imageModel.ImageSize === ImageDisplayMode.CustomSize && imageModel.Width ? imageModel.Width : undefined}
height={imageModel.ImageSize === ImageDisplayMode.CustomSize && imageModel.Height ? imageModel.Height : undefined}
loading="lazy"
className={imageClass ? className : undefined}
src={selectedImageUrl}
title={imageModel.Title}
alt={altAttr ? altAttr : undefined} />
}
</span>);
}
26 changes: 13 additions & 13 deletions src/nextjs-framework/widgets/image/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,18 @@ import { ImageTag } from './image-tag';
import { ImageClickAction } from './interfaces/ImageClickAction';
import { ImageDisplayMode } from './interfaces/ImageDisplayMode';
import { WidgetContext, htmlAttributes, classNames, generateAnchorAttrsFromLink, LinkModel } from '../../editor';
import { RestService, RestSdkTypes, ThumbnailItem, SdkItem, ImageItem } from '../../rest-sdk';
import { RestService, RestSdkTypes, ThumbnailItem, ImageItem, SdkItem } from '../../rest-sdk';

const imageWrapperClass = 'd-inline-block';

export async function Image(props: WidgetContext<ImageEntity>) {
const entity = {
const entity: ImageEntity = {
ImageSize: ImageDisplayMode.Responsive,
...props.model.Properties
};
const dataAttributes = htmlAttributes(props);
const defaultClass = classNames(imageWrapperClass, entity.CssClass);
const marginClass = entity.Margins && StyleGenerator.getMarginClasses(entity.Margins);
const anchorAttributes = generateAnchorAttrsFromLink(entity.ActionLink);
dataAttributes['className'] = classNames(
defaultClass,
marginClass
);

dataAttributes['data-sfhasquickeditoperation'] = true;
let imageItem = null;
if (entity.Item && entity.Item.Id) {
imageItem = await RestService.getItemWithFallback(RestSdkTypes.Image, entity.Item.Id.toString(), entity.Item.Provider);
Expand All @@ -33,6 +26,13 @@ export async function Image(props: WidgetContext<ImageEntity>) {
return (<div {...dataAttributes} />);
}

const defaultClass = classNames(imageWrapperClass, entity.CssClass);
const marginClass = entity.Margins && StyleGenerator.getMarginClasses(entity.Margins);
dataAttributes['className'] = classNames(
defaultClass,
marginClass
);

const isSvg = imageItem.MimeType === 'image/svg+xml';
const hasZeroDimensions = imageItem.Width === 0 && imageItem.Height === 0;
let width = isSvg && hasZeroDimensions ? null : imageItem.Width;
Expand Down Expand Up @@ -91,17 +91,17 @@ export async function Image(props: WidgetContext<ImageEntity>) {
}

export interface ImageEntity {
Item?: ImageItem;
Attributes?: { [key: string]: Array<{ Key: string, Value: string}> };
Margins?: OffsetStyle;
Item?: SdkItem;
CssClass?: string;
Title?: string;
AlternativeText?: string;
CssClass?: string;
ClickAction?: ImageClickAction;
ActionLink?: LinkModel;
ImageSize?: ImageDisplayMode;
FitToContainer: boolean;
CustomSize?: { Width: number, Height: number};
Thumnail?: ThumbnailItem;
ViewName?: string;
Margins?: OffsetStyle;
Attributes?: { [key: string]: Array<{ Key: string, Value: string}> };
}
6 changes: 4 additions & 2 deletions src/nextjs-framework/widgets/widget-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ export const widgetRegistry: WidgetRegistry = {
Section: 'Basic',
EmptyIcon: 'picture-o',
EmptyIconAction: 'Edit',
EmptyIconText: 'Select image'
EmptyIconText: 'Select image',
HasQuickEditOperation: true
},
ssr: true
},
Expand Down Expand Up @@ -164,7 +165,8 @@ export const widgetRegistry: WidgetRegistry = {
componentType: ContentBlock,
editorMetadata: {
Title: 'Content block',
Section: 'Basic'
Section: 'Basic',
HasQuickEditOperation: true
},
ssr: true
},
Expand Down
40 changes: 5 additions & 35 deletions tests/__snapshots__/image.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,43 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Image with selected image item 1`] = `
exports[`Image rendered with original size 1`] = `
<div>
<picture
class="d-inline-block"
data-sfhasquickeditoperation="true"
>
<source
height="160"
media="(max-width: 160px)"
type="image/jpeg"
width="160"
/>
<span>
<img
alt=""
class="d-inline-block img-fluid"
loading="lazy"
title="Image"
src="/images/default-source/default-album/imagee7f8cd11-dafa-41c6-95bb-7100514c09dd.jpg?sfvrsn=87c70c89_2"
title="custom title"
/>
</picture>
</div>
`;

exports[`should render image default state 1`] = `
<div>
<div
class="d-inline-block"
data-sfemptyicon="picture-o"
data-sfemptyiconaction="Edit"
data-sfemptyicontext="Select image"
data-sfhasquickeditoperation="true"
data-sfid="568481ca-45db-4f02-a62e-f76122532902"
data-sfiscontentwidget="true"
data-sfisempty="false"
data-sfisemptyvisualhidden="false"
data-sfisorphaned="false"
data-sfname="SitefinityImage"
data-sftitle="Image"
draggable="true"
/>
</span>
</div>
`;
6 changes: 5 additions & 1 deletion tests/framework/widget-tester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ export class WidgetTester {
if (args.properties) {
Object.keys(args.properties).forEach((key) => {
let value: any = (args.properties as any)[key];
if (value && !(typeof value === 'undefined')) {
if (typeof value === 'object') {
value = JSON.stringify(value);
} else if (typeof value !== 'undefined') {
value = value.toString();
} else {
return;
}

properties[key] = value;
Expand Down
36 changes: 30 additions & 6 deletions tests/image.test.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
import { waitFor } from '@testing-library/react';
import { WidgetTester } from './framework/widget-tester';
import { RestSdkTypes, RestService } from '../src/nextjs-framework/rest-sdk';
import { RestSdkTypes, RestService, SdkItem } from '../src/nextjs-framework/rest-sdk';
import fs from 'fs';
import { ImageEntity } from '../src/nextjs-framework/widgets/image/image';
import { ImageDisplayMode } from '../src/nextjs-framework/widgets/image/interfaces/ImageDisplayMode';


test('Image with selected image item', async () => {
let sdkItem: SdkItem;
beforeAll(async () => {
const base64Image = fs.readFileSync('./tests/data/1.jpg', { encoding: 'base64' });

let libraryId = '4BA7AD46-F29B-4e65-BE17-9BF7CE5BA1FB';
const imageItem = await RestService.uploadItem({
sdkItem = await RestService.uploadItem({
Title: 'Image',
Type: RestSdkTypes.Image,
ContentType: 'image/jpeg',
FileName: 'test.jpg',
ParentId: libraryId,
BinaryData: base64Image
});
});

test('Image rendered with original size', async () => {
await WidgetTester.testWidgetRender<ImageEntity>({
name: 'SitefinityImage',
properties: {
Item: {
Id: sdkItem.Id,
Provider: sdkItem.Provider
},
FitToContainer: false,
ImageSize: ImageDisplayMode.OriginalSize,
Title: 'custom title'
},
assert: async (element) => {
await waitFor(() => {
expect(element).toMatchSnapshot();
});
}
});
});

test('Image with selected image item', async () => {
await WidgetTester.testWidgetRender({
name: 'SitefinityImage',
properties: {
Item: {
Id: imageItem.Id,
Provider: imageItem.Provider
Id: sdkItem.Id,
Provider: sdkItem.Provider
}
},
assert: async (element) => {
Expand Down

0 comments on commit b4413c3

Please sign in to comment.