From 4efbc33893f85ae9729c7c1d69764e6f38468d5d Mon Sep 17 00:00:00 2001 From: Siklos Date: Sun, 7 Aug 2022 15:20:17 +0200 Subject: [PATCH 1/2] Allow to start from scratch with a default config --- src/App.tsx | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 705e40d..263827b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -100,8 +100,39 @@ export class App extends React.Component { historyCurrentStep: 0, isLoaded: true }); - }, (error) => { throw new Error(error); } - ); + }, (error) => { + // TODO: Implement an alert component + console.warn('[NewEditor] Could not fetch resource from API. Returning default.', error); + const MainContainer = new ContainerModel( + null, + { + id: 'main', + parentId: 'null', + x: 0, + y: 0, + width: DEFAULT_CONFIG.MainContainer.Width, + height: DEFAULT_CONFIG.MainContainer.Height, + fillOpacity: DEFAULT_CONFIG.MainContainer.Style.fillOpacity, + stroke: DEFAULT_CONFIG.MainContainer.Style.stroke, + } + ); + + // Save the configuration and the new MainContainer + // and default the selected container to it + this.setState({ + configuration: DEFAULT_CONFIG, + history: + [ + { + MainContainer, + SelectedContainer: MainContainer, + TypeCounters: {} + } + ], + historyCurrentStep: 0, + isLoaded: true + }); + }); } public LoadEditor(files: FileList | null): void { @@ -182,3 +213,28 @@ export async function fetchConfiguration(): Promise { xhr.send(); }); } + + +const DEFAULT_CONFIG: Configuration = { + AvailableContainers: [ + { + Type: 'Container', + Width: 75, + Height: 100, + Style: { + fillOpacity: 0, + stroke: 'green' + } + } + ], + AvailableSymbols: [], + MainContainer: { + Type: 'Container', + Width: 2000, + Height: 100, + Style: { + fillOpacity: 0, + stroke: 'black' + } + } +} From 2d048df3fe47dd645d5c96d3a9431990307313e0 Mon Sep 17 00:00:00 2001 From: Siklos Date: Sun, 7 Aug 2022 15:59:16 +0200 Subject: [PATCH 2/2] Add tests for elements sidebar --- .../ElementsSidebar/ElementsSidebar.test.tsx | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 src/Components/ElementsSidebar/ElementsSidebar.test.tsx diff --git a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx new file mode 100644 index 0000000..d52fe97 --- /dev/null +++ b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx @@ -0,0 +1,242 @@ +import { describe, test, expect, vi } from 'vitest'; +import * as React from 'react'; +import { fireEvent, render, screen } from '../../utils/test-utils'; +import { ElementsSidebar } from './ElementsSidebar'; +import { IContainerModel } from '../../Interfaces/ContainerModel'; + +describe.concurrent('Elements sidebar', () => { + it('No elements', () => { + render( {}} + onPropertyChange={() => {}} + selectContainer={() => {}} + />); + + expect(screen.getByText(/Elements/i)); + expect(screen.queryByText('id')).toBeNull(); + expect(screen.queryByText(/main/i)).toBeNull(); + }); + + it('With a MainContainer', () => { + render( {}} + onPropertyChange={() => {}} + selectContainer={() => {}} + />); + + expect(screen.getByText(/Elements/i)); + expect(screen.queryByText('id')).toBeNull(); + expect(screen.getByText(/main/i)); + }); + + it('With a selected MainContainer', () => { + const MainContainer = { + children: [], + parent: null, + properties: { + id: 'main', + parentId: '', + x: 0, + y: 0, + width: 2000, + height: 100 + }, + userData: {} + }; + + const { container } = render( {}} + onPropertyChange={() => {}} + selectContainer={() => {}} + />); + + expect(screen.getByText(/Elements/i)); + expect(screen.getByText(/main/i)); + expect(screen.queryByText('id')).toBeDefined(); + expect(screen.queryByText('parentId')).toBeDefined(); + expect(screen.queryByText('x')).toBeDefined(); + expect(screen.queryByText('y')).toBeDefined(); + expect(screen.queryByText('width')).toBeDefined(); + expect(screen.queryByText('height')).toBeDefined(); + const propertyId = container.querySelector('#property-id'); + const propertyParentId = container.querySelector('#property-parentId'); + const propertyX = container.querySelector('#property-x'); + const propertyY = container.querySelector('#property-y'); + const propertyWidth = container.querySelector('#property-width'); + const propertyHeight = container.querySelector('#property-height'); + expect((propertyId as HTMLInputElement).value).toBe(MainContainer.properties.id.toString()); + expect(propertyParentId).toBeDefined(); + expect((propertyParentId as HTMLInputElement).value).toBe(''); + expect(propertyX).toBeDefined(); + expect((propertyX as HTMLInputElement).value).toBe(MainContainer.properties.x.toString()); + expect(propertyY).toBeDefined(); + expect((propertyY as HTMLInputElement).value).toBe(MainContainer.properties.y.toString()); + expect(propertyWidth).toBeDefined(); + expect((propertyWidth as HTMLInputElement).value).toBe(MainContainer.properties.width.toString()); + expect(propertyHeight).toBeDefined(); + expect((propertyHeight as HTMLInputElement).value).toBe(MainContainer.properties.height.toString()); + }); + + it('With multiple containers', () => { + const children: IContainerModel[] = []; + const MainContainer = { + children, + parent: null, + properties: { + id: 'main', + parentId: '', + x: 0, + y: 0, + width: 2000, + height: 100 + }, + userData: {} + }; + + children.push( + { + children: [], + parent: MainContainer, + properties: { + id: 'child-1', + parentId: 'main', + x: 0, + y: 0, + width: 0, + height: 0 + }, + userData: {} + } + ); + + children.push( + { + children: [], + parent: MainContainer, + properties: { + id: 'child-2', + parentId: 'main', + x: 0, + y: 0, + width: 0, + height: 0 + }, + userData: {} + } + ); + + render( {}} + onPropertyChange={() => {}} + selectContainer={() => {}} + />); + + expect(screen.getByText(/Elements/i)); + expect(screen.queryByText('id')).toBeDefined(); + expect(screen.getByText(/main/i)); + expect(screen.getByText(/child-1/i)); + expect(screen.getByText(/child-2/i)); + }); + + it('With multiple containers, change selection', () => { + const children: IContainerModel[] = []; + const MainContainer: IContainerModel = { + children, + parent: null, + properties: { + id: 'main', + parentId: '', + x: 0, + y: 0, + width: 2000, + height: 100 + }, + userData: {} + }; + + const child1Model: IContainerModel = { + children: [], + parent: MainContainer, + properties: { + id: 'child-1', + parentId: 'main', + x: 0, + y: 0, + width: 0, + height: 0 + }, + userData: {} + }; + children.push(child1Model); + + let SelectedContainer = MainContainer; + const selectContainer = vi.fn((container: IContainerModel) => { + SelectedContainer = container; + }); + + const { container, rerender } = render( {}} + onPropertyChange={() => {}} + selectContainer={selectContainer} + />); + + expect(screen.getByText(/Elements/i)); + expect(screen.queryByText('id')).toBeDefined(); + expect(screen.getByText(/main/i)); + const child1 = screen.getByText(/child-1/i); + expect(child1); + const propertyId = container.querySelector('#property-id'); + const propertyParentId = container.querySelector('#property-parentId'); + expect((propertyId as HTMLInputElement).value).toBe(MainContainer.properties.id.toString()); + expect((propertyParentId as HTMLInputElement).value).toBe(''); + + fireEvent.click(child1); + + rerender( {}} + onPropertyChange={() => {}} + selectContainer={selectContainer} + />); + + expect((propertyId as HTMLInputElement).value === 'main').toBeFalsy(); + expect((propertyParentId as HTMLInputElement).value === '').toBeFalsy(); + expect((propertyId as HTMLInputElement).value).toBe(child1Model.properties.id.toString()); + expect((propertyParentId as HTMLInputElement).value).toBe(child1Model.properties.parentId?.toString()); + }); +});