-
-
- } />
-
-
showSearch(false)} title={'Close search'}>
-
-
+
+
+
+ Search
+
+ } />
+
+
+
+
+ {searchSupport}
+
+ Results
+ {searchTerm}
+ {renderedResults}
-
Search
-
- setSearchTerm(event.target.value)}
- startAdornment={
- setRender(!render)} title={'Show results'}>
-
-
- }
- endAdornment={
- searchTerm.length ? (
-
- clear()} title={'Clear'}>
-
-
-
- ) : null
- }
- />
- {searchSupport}
-
);
};
diff --git a/src/main/app/src/Components/Landscape/Search/SearchField.test.tsx b/src/main/app/src/Components/Landscape/Search/SearchField.test.tsx
new file mode 100644
index 000000000..81e896939
--- /dev/null
+++ b/src/main/app/src/Components/Landscape/Search/SearchField.test.tsx
@@ -0,0 +1,10 @@
+import { getByDisplayValue, render } from '@testing-library/react';
+import React from 'react';
+import SearchField from './SearchField';
+
+describe('
', () => {
+ it('should render', () => {
+ const { getByDisplayValue } = render(
{}} />);
+ expect(getByDisplayValue('')).toBeInTheDocument();
+ });
+});
diff --git a/src/main/app/src/Components/Landscape/Search/SearchField.tsx b/src/main/app/src/Components/Landscape/Search/SearchField.tsx
new file mode 100644
index 000000000..d5aa9a7ef
--- /dev/null
+++ b/src/main/app/src/Components/Landscape/Search/SearchField.tsx
@@ -0,0 +1,87 @@
+import React, { useEffect, useState } from 'react';
+
+import { Input, InputAdornment, Theme } from '@material-ui/core';
+import { Backspace, SearchOutlined } from '@material-ui/icons';
+import IconButton from '@material-ui/core/IconButton';
+import { createStyles, makeStyles } from '@material-ui/core/styles';
+import Search from './Search';
+
+const useStyles = makeStyles((theme: Theme) =>
+ createStyles({
+ search: {
+ margin: 0,
+ marginLeft: 10,
+ padding: 0,
+ paddingLeft: 5,
+ borderRadius: 50,
+ height: '2.5em',
+ border: '1px solid ',
+ backgroundColor: theme.palette.background.default,
+ borderColor: theme.palette.primary.main,
+ },
+ searchField: {
+ marginTop: 0,
+ paddingLeft: 5,
+ paddingRight: 5,
+ width: '100%',
+ },
+ })
+);
+
+interface Props {
+ setSidebarContent: Function;
+}
+
+/**
+ * Search input field displayed in the top nav
+ *
+ * @param setSidebarContent function the set content to the drawer sidebar
+ */
+const SearchField: React.FC = ({ setSidebarContent }) => {
+ const classes = useStyles();
+ const [searchTerm, setSearchTerm] = useState('');
+ const searchInput = React.useRef(null);
+
+ const update = () => {
+ setSidebarContent();
+ };
+
+ useEffect(() => {
+ setSidebarContent();
+ }, [searchTerm, setSidebarContent]);
+
+ function clear() {
+ setSearchTerm('');
+ }
+
+ return (
+
+ setSearchTerm(event.target.value)}
+ onFocus={() => update()}
+ endAdornment={
+
+ {searchTerm.length ? (
+ clear()} title={'Clear'}>
+
+
+ ) : (
+ <>>
+ )}
+ update()} title={'Show results'}>
+
+
+
+ }
+ />
+
+ );
+};
+
+export default SearchField;
diff --git a/src/main/app/src/Components/Landscape/Utils/utils.tsx b/src/main/app/src/Components/Landscape/Utils/utils.tsx
index 39f18915e..909c8a683 100644
--- a/src/main/app/src/Components/Landscape/Utils/utils.tsx
+++ b/src/main/app/src/Components/Landscape/Utils/utils.tsx
@@ -1,6 +1,6 @@
-import React, { ReactElement } from 'react';
-import { IGroup, IItem, ILandscape, IRelation } from '../../../interfaces';
-import { Button, Link, List, ListItem, ListItemText } from '@material-ui/core';
+import React, {ReactElement} from 'react';
+import {IGroup, IItem, ILandscape, IRelation} from '../../../interfaces';
+import {Button, Link, List, ListItem, ListItemText} from '@material-ui/core';
import MappedString from './MappedString';
/**
@@ -30,7 +30,10 @@ export const getItem = (landscape: ILandscape, fullyQualifiedIdentifier: string)
* @param landscape object
* @param fullyQualifiedIdentifier string to identify the group
*/
-export const getGroup = (landscape: ILandscape, fullyQualifiedIdentifier: string): IGroup | null => {
+export const getGroup = (
+ landscape: ILandscape,
+ fullyQualifiedIdentifier: string
+): IGroup | null => {
let group: IGroup | null = null;
for (let i = 0; i < landscape.groups.length; i++) {
let value = landscape.groups[i];
@@ -157,9 +160,10 @@ export const getLabelsWithPrefix = (prefix: string, element: IGroup | IItem) =>
const value = element.labels?.[key] || null;
if (!value) return;
const primary = key.replace(prefix + '.', '');
+ const secondary = value.substr(0, 150);
labels.push(
-
+
);
});
diff --git a/src/main/app/src/Components/Layout/Layout.test.tsx b/src/main/app/src/Components/Layout/Layout.test.tsx
new file mode 100644
index 000000000..b3d947da6
--- /dev/null
+++ b/src/main/app/src/Components/Layout/Layout.test.tsx
@@ -0,0 +1,22 @@
+import { getByAltText, render } from '@testing-library/react';
+import React from 'react';
+import Layout from './Layout';
+import { MemoryRouter } from 'react-router-dom';
+
+describe('', () => {
+ it('should render navigation with title, logo and version', () => {
+ const { getByText, getByAltText } = render(
+
+ }
+ version={'123'}
+ />
+
+ );
+ expect(getByAltText('logo')).toHaveAttribute('src', 'https://acme.com/logo.png');
+ expect(getByText('foo')).toBeInTheDocument();
+ expect(getByText('nivio 123')).toBeInTheDocument();
+ });
+});
diff --git a/src/main/app/src/Components/Layout/Layout.tsx b/src/main/app/src/Components/Layout/Layout.tsx
index 2b23b8f44..77888ba8b 100644
--- a/src/main/app/src/Components/Layout/Layout.tsx
+++ b/src/main/app/src/Components/Layout/Layout.tsx
@@ -1,106 +1,94 @@
-import React, { ReactElement } from 'react';
+import React, { ReactElement, useContext, useEffect, useState } from 'react';
import Navigation from '../Navigation/Navigation';
import { Drawer, Theme } from '@material-ui/core';
import { createStyles, makeStyles } from '@material-ui/core/styles';
-import Search from '../Landscape/Search/Search';
+import IconButton from '@material-ui/core/IconButton';
+import { CloseSharp } from '@material-ui/icons';
+import { LandscapeContext } from '../../Context/LandscapeContext';
interface Props {
children: string | ReactElement | ReactElement[];
- sidebarContent: string | ReactElement | ReactElement[];
- setSidebarContent: Function;
pageTitle?: string;
logo?: string;
version?: string;
}
-const searchSupportWidth = 360;
-const sidebarWidth = 280;
+const drawerWidth = 360;
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
},
- sideBar: {
- position: 'absolute',
- right: 0,
- top: 5,
- width: sidebarWidth,
- overflow: 'auto',
- maxHeight: 'calc(100vh - 50px)',
- zIndex: 5000,
- },
-
- outer: {
- display: 'flex',
- flexDirection: 'row',
- },
- content: {
- position: 'relative',
- },
+ outer: {},
flexItem: {
flexShrink: 1,
flexGrow: 1,
},
main: {
+ display: 'flex',
+ flexDirection: 'row',
+ },
+ children: {
flexShrink: 1,
flexGrow: 2,
width: '1000px',
},
- searchSupport: {
+ sidebar: {
backgroundColor: theme.palette.primary.dark,
- width: searchSupportWidth,
+ width: drawerWidth,
padding: 5,
+ top: 0,
+ position: 'absolute',
},
})
);
/**
* Contains our site layout, Navigation on top, content below
- * @param param0
*/
-const Layout: React.FC
= ({
- children,
- sidebarContent,
- setSidebarContent,
- pageTitle,
- logo,
- version,
-}) => {
+const Layout: React.FC = ({ children, pageTitle, logo, version }) => {
const classes = useStyles();
- const [searchSupport, setSearchSupport] = React.useState(false);
+ const [sidebarContent, setSidebarContent] = useState(null);
+ const [sidebarOpen, setSidebarOpen] = useState(false);
+ const landscapeContext = useContext(LandscapeContext);
+
+ useEffect(() => {
+ const isOpen = sidebarContent != null && landscapeContext.identifier != null;
+ setSidebarOpen(isOpen);
+ }, [sidebarContent, landscapeContext]);
return (
+
-
-
-
{sidebarContent}
- {children}
-
+ {children}
+
+
+ setSidebarOpen(false)} size={'small'}>
+
+
+
+ {sidebarContent}
+
-
{
- setSearchSupport(false);
- }}
- >
-
-
);
};
diff --git a/src/main/app/src/Components/Manual/Man.css b/src/main/app/src/Components/Manual/Man.css
index 1b117fbb2..7bb83c6b2 100644
--- a/src/main/app/src/Components/Manual/Man.css
+++ b/src/main/app/src/Components/Manual/Man.css
@@ -5,3 +5,7 @@ a.reference.external {
.highlight {
background-color: #333333;
}
+
+.footer {
+ display: none;
+}
diff --git a/src/main/app/src/Components/Manual/Man.tsx b/src/main/app/src/Components/Manual/Man.tsx
index cdd83c8aa..a18c31911 100644
--- a/src/main/app/src/Components/Manual/Man.tsx
+++ b/src/main/app/src/Components/Manual/Man.tsx
@@ -14,8 +14,14 @@ const useStyles = makeStyles((theme: Theme) =>
createStyles({
manualContainer: {
overflowY: 'scroll',
- height: '90vh',
- marginRight: 340,
+ height: '99vh',
+ padding: 10,
+ display: 'flex',
+ },
+ sidebar: {
+ width: 330,
+ flexShrink: 1,
+ flexGrow: 1,
},
link: {
color: theme.palette.primary.contrastText,
@@ -27,14 +33,13 @@ const useStyles = makeStyles((theme: Theme) =>
);
interface Props {
- setSidebarContent: Function;
setPageTitle: Function;
}
/**
* Renders nivio manual, depending on which url param is given
*/
-const Man: React.FC = ({ setSidebarContent, setPageTitle }) => {
+const Man: React.FC = ({ setPageTitle }) => {
const classes = useStyles();
const [html, setHtml] = useState(
@@ -45,6 +50,7 @@ const Man: React.FC = ({ setSidebarContent, setPageTitle }) => {
if (usage == null || typeof usage == 'undefined') usage = 'index';
const [topic, setTopic] = useState(usage + '');
const [side, setSide] = useState(null);
+ const [sidebarContent, setSidebarContent] = useState([]);
const [emptyManual, setemptyManual] = useState(false);
const handleSphinxSidebar = useCallback(
@@ -191,6 +197,7 @@ const Man: React.FC = ({ setSidebarContent, setPageTitle }) => {
return (
{html}
+ {sidebarContent}
);
};
diff --git a/src/main/app/src/Components/Navigation/Navigation.test.tsx b/src/main/app/src/Components/Navigation/Navigation.test.tsx
index 9e3c35aac..4b04e53e4 100644
--- a/src/main/app/src/Components/Navigation/Navigation.test.tsx
+++ b/src/main/app/src/Components/Navigation/Navigation.test.tsx
@@ -8,21 +8,23 @@ global.TextEncoder = TextEncoder;
// @ts-ignore
global.TextDecoder = TextDecoder;
-it('should render Home link', () => {
- const { getByText } = render(
-
- {}} />
-
- );
- expect(getByText('Home')).toBeInTheDocument();
-});
+describe('', () => {
+ it('should render Home link', () => {
+ const { getByText } = render(
+
+ {}} />
+
+ );
+ expect(getByText('Home')).toBeInTheDocument();
+ });
-it('should link to manual on button click', () => {
- const { getByText } = render(
-
- {}} />
-
- );
+ it('should link to manual on button click', () => {
+ const { getByText } = render(
+
+ {}} />
+
+ );
- expect(getByText('Help').closest('a')).toHaveAttribute('href', '/man/install.html');
+ expect(getByText('Help').closest('a')).toHaveAttribute('href', '/man/install.html');
+ });
});
diff --git a/src/main/app/src/Components/Navigation/Navigation.tsx b/src/main/app/src/Components/Navigation/Navigation.tsx
index f1867c77e..fce9afed1 100644
--- a/src/main/app/src/Components/Navigation/Navigation.tsx
+++ b/src/main/app/src/Components/Navigation/Navigation.tsx
@@ -18,27 +18,24 @@ import IconButton from '@material-ui/core/IconButton';
import Avatar from '@material-ui/core/Avatar';
import { withBasePath } from '../../utils/API/BasePath';
import Notification from '../Notification/Notification';
-import { SearchOutlined } from '@material-ui/icons';
import componentStyles from '../../Resources/styling/ComponentStyles';
import LandscapeWatcher from '../Landscape/Dashboard/LandscapeWatcher';
import { LandscapeContext } from '../../Context/LandscapeContext';
+import SearchField from '../Landscape/Search/SearchField';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
- grow: {
- flexGrow: 1,
- },
pageTitle: {
padding: 11,
paddingLeft: 16,
paddingRight: 16,
+ flexGrow: 1,
},
logo: {
height: '1.5em',
width: '1.5em',
},
appBar: {
- zIndex: theme.zIndex.drawer + 1,
position: 'relative',
backgroundColor: theme.palette.primary.main,
},
@@ -47,8 +44,6 @@ const useStyles = makeStyles((theme: Theme) =>
interface Props {
setSidebarContent: Function;
- setSearchSupport: Function;
- searchSupport: boolean;
pageTitle?: string;
logo?: string;
version?: string;
@@ -57,14 +52,7 @@ interface Props {
/**
* Header Component
*/
-const Navigation: React.FC = ({
- setSidebarContent,
- setSearchSupport,
- searchSupport,
- pageTitle,
- logo,
- version,
-}) => {
+const Navigation: React.FC = ({ setSidebarContent, pageTitle, logo, version }) => {
const classes = useStyles();
const componentClasses = componentStyles();
const landscapeContext = useContext(LandscapeContext);
@@ -110,12 +98,14 @@ const Navigation: React.FC = ({
className={classes.logo}
imgProps={{ style: { objectFit: 'contain' } }}
src={logo}
+ alt={'logo'}
/>
) : (
)}
@@ -133,17 +123,11 @@ const Navigation: React.FC = ({
{pageTitle}
+ {landscapeContext.identifier ? : null}
+
{landscapeContext.identifier ? (
- setSearchSupport(!searchSupport)}
- title={'Toggle search'}
- >
-
-
+
) : null}{' '}
-
-
);
};
diff --git a/src/main/app/src/Components/Notification/Changes.tsx b/src/main/app/src/Components/Notification/Changes.tsx
index a4d50898e..b44d67cc3 100644
--- a/src/main/app/src/Components/Notification/Changes.tsx
+++ b/src/main/app/src/Components/Notification/Changes.tsx
@@ -1,15 +1,15 @@
-import React, { ReactElement, useContext, useEffect, useState } from 'react';
-import { IChange } from '../../interfaces';
-import { Card, CardHeader, Table, TableBody, TableCell, TableRow } from '@material-ui/core';
-import { get } from '../../utils/API/APIClient';
+import React, {ReactElement, useContext, useEffect, useState} from 'react';
+import {IChange} from '../../interfaces';
+import {Box, Table, TableBody, TableCell, TableRow, Typography} from '@material-ui/core';
+import {get} from '../../utils/API/APIClient';
import IconButton from '@material-ui/core/IconButton';
import ItemAvatar from '../Landscape/Modals/Item/ItemAvatar';
import componentStyles from '../../Resources/styling/ComponentStyles';
-import { LocateFunctionContext } from '../../Context/LocateFunctionContext';
+import {LocateFunctionContext} from '../../Context/LocateFunctionContext';
import GroupAvatar from '../Landscape/Modals/Group/GroupAvatar';
-import { Close, LinkOutlined } from '@material-ui/icons';
+import {LinkOutlined} from '@material-ui/icons';
import Button from '@material-ui/core/Button';
-import { LandscapeContext } from '../../Context/LandscapeContext';
+import {LandscapeContext} from '../../Context/LandscapeContext';
/**
* Displays the changes of an ProcessingFinishedEvent
@@ -21,23 +21,18 @@ const Changes: React.FC = () => {
const [renderedChanges, setRenderedChanges] = useState([]);
const locateFunctionContext = useContext(LocateFunctionContext);
const landscapeContext = useContext(LandscapeContext);
- const [visible, setVisible] = useState(true);
-
- const close = (
- {
- setVisible(false);
- }}
- >
-
-
- );
/**
* render changes, calling api for component info
*/
useEffect(() => {
- if (landscapeContext.changes == null) return;
+ if (
+ landscapeContext.changes == null ||
+ landscapeContext.changes.landscape !== landscapeContext.identifier
+ ) {
+ setRenderedChanges([]);
+ return;
+ }
const getItemChange = (key: string, change: IChange): Promise => {
if (change.changeType === 'DELETED') {
@@ -133,8 +128,8 @@ const Changes: React.FC = () => {
};
let promises: Promise[] = [];
- for (let key of Object.keys(landscapeContext.changes)) {
- let change = landscapeContext.changes[key];
+ for (let key of Object.keys(landscapeContext.changes.changelog.changes)) {
+ let change = landscapeContext.changes.changelog.changes[key];
switch (change.componentType) {
case 'Item':
@@ -151,17 +146,22 @@ const Changes: React.FC = () => {
Promise.all(promises).then((rows) => {
setRenderedChanges(rows);
});
- }, [ componentClasses.card, locateFunctionContext, landscapeContext]);
-
- if (!visible) return null;
+ }, [componentClasses.card, locateFunctionContext, landscapeContext]);
return (
-
-
-
- {landscapeContext.changes != null ? renderedChanges : null}
-
-
+
+
+ Latest changes
+ {landscapeContext.landscape?.name}
+
+ {landscapeContext.changes != null ? (
+
+ ) : (
+ No changes recorded yet.
+ )}
+
);
};
diff --git a/src/main/app/src/Components/Notification/Notification.tsx b/src/main/app/src/Components/Notification/Notification.tsx
index 5203c4d7b..a3a03b65d 100644
--- a/src/main/app/src/Components/Notification/Notification.tsx
+++ b/src/main/app/src/Components/Notification/Notification.tsx
@@ -1,10 +1,10 @@
-import React, {ReactElement, useContext, useEffect, useState} from 'react';
+import React, { useContext, useEffect, useState } from 'react';
import IconButton from '@material-ui/core/IconButton';
-import {Badge} from '@material-ui/core';
-import {Notifications} from '@material-ui/icons';
+import { Badge } from '@material-ui/core';
+import { Notifications } from '@material-ui/icons';
import Changes from './Changes';
import componentStyles from '../../Resources/styling/ComponentStyles';
-import {LandscapeContext} from '../../Context/LandscapeContext';
+import { LandscapeContext } from '../../Context/LandscapeContext';
interface Props {
setSidebarContent: Function;
@@ -18,7 +18,6 @@ interface Props {
const Notification: React.FC = ({ setSidebarContent }) => {
const classes = componentStyles();
const [newChanges, setNewChanges] = useState(false);
- const [renderedChanges, setRenderedChanges] = useState(null);
const landscapeContext = useContext(LandscapeContext);
/**
@@ -26,7 +25,6 @@ const Notification: React.FC = ({ setSidebarContent }) => {
*/
useEffect(() => {
if (landscapeContext.changes == null) return;
- setRenderedChanges();
setNewChanges(true);
}, [landscapeContext.changes]);
@@ -43,7 +41,7 @@ const Notification: React.FC = ({ setSidebarContent }) => {
className={classes.navigationButton}
onClick={() => {
setNewChanges(false);
- return setSidebarContent(renderedChanges);
+ return setSidebarContent();
}}
>
diff --git a/src/main/app/src/Context/LandscapeContext.tsx b/src/main/app/src/Context/LandscapeContext.tsx
index 31213a8d4..12c95f283 100644
--- a/src/main/app/src/Context/LandscapeContext.tsx
+++ b/src/main/app/src/Context/LandscapeContext.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { IAssessment, IAssessmentProps, IChanges, ILandscape, INotificationMessage } from "../interfaces";
+import { IAssessment, IAssessmentProps, ILandscape, INotificationMessage } from '../interfaces';
import { get } from '../utils/API/APIClient';
import { withBasePath } from '../utils/API/BasePath';
import { Client, StompSubscription } from '@stomp/stompjs';
@@ -9,7 +9,7 @@ export interface LandscapeContextType {
readonly assessment: IAssessment | null;
readonly identifier: string | null;
readonly notification: INotificationMessage | null;
- readonly changes: IChanges | null;
+ readonly changes: INotificationMessage | null;
next: (identifier: string | null) => void;
getAssessmentSummary: (fqi: string) => IAssessmentProps | null;
}
@@ -39,7 +39,7 @@ const LandscapeContextProvider: React.FC = (props) => {
const [landscape, setLandscape] = useState(null);
const [assessment, setAssessment] = useState(null);
const [notification, setNotification] = useState(null);
- const [changes, setChanges] = useState(null);
+ const [changes, setChanges] = useState(null);
const [identifier, setIdentifier] = useState(null);
const backendUrl = withBasePath('/subscribe');
@@ -62,8 +62,9 @@ const LandscapeContextProvider: React.FC = (props) => {
if (notificationMessage.type === 'LayoutChangedEvent') {
setNotification(notificationMessage);
}
+
if (notificationMessage.type === 'ProcessingFinishedEvent') {
- setChanges(notificationMessage.changelog.changes);
+ setChanges(notificationMessage);
}
});
@@ -102,6 +103,7 @@ const LandscapeContextProvider: React.FC = (props) => {
setAssessment(response);
console.debug(`Loaded assessment data after identifier change: ${identifier}`);
});
+ setChanges(null);
}, [identifier]);
/**
@@ -113,10 +115,12 @@ const LandscapeContextProvider: React.FC = (props) => {
return;
}
- get(`/assessment/${identifier}`).then((response) => {
- console.debug(`Loaded assessment data for ${identifier}`, response);
- setAssessment(response);
- });
+ if (identifier === notification?.landscape) {
+ get(`/assessment/${identifier}`).then((response) => {
+ console.debug(`Loaded assessment data for ${identifier}`, response);
+ setAssessment(response);
+ });
+ }
}, [identifier, notification]);
return (
diff --git a/src/main/app/src/interfaces.ts b/src/main/app/src/interfaces.ts
index 104e33625..63e8419ba 100644
--- a/src/main/app/src/interfaces.ts
+++ b/src/main/app/src/interfaces.ts
@@ -90,6 +90,7 @@ export interface IGroup {
labels?: ILabels;
_links?: ILinks;
items: IItem[];
+ icon: string;
}
export interface IItem {
@@ -109,6 +110,7 @@ export interface IItem {
color?: string;
icon: string;
_links?: ILinks;
+ networks: Array;
}
export interface IInterfaces {
@@ -217,10 +219,11 @@ export interface IFacet {
/**
* different label counts
*/
- labelValues: ILabelValue[];
+ labelValues: IChipValue[];
}
-export interface ILabelValue {
+export interface IChipValue {
label: string;
value: number;
+ color: string;
}
diff --git a/src/main/app/src/labels.json b/src/main/app/src/labels.json
index 4edfa1454..886f13896 100644
--- a/src/main/app/src/labels.json
+++ b/src/main/app/src/labels.json
@@ -1,22 +1 @@
-{
- "capability": "The capability the service provides for the business or, in case of infrastructure, the technical capability like enabling service discovery, configuration, secrets, or persistence.",
- "color": "A hex color code (items inherit group colors as default)",
- "costs": "Running costs of the item.",
- "fill": "Background image (for displaying purposes).",
- "frameworks": "A comma-separated list of frameworks as key-value pairs (key is name, value is version).",
- "health": "Description of the item's health status.",
- "icon": "Icon/image (for displaying purposes).",
- "label": "A custom label (like a note, but very short).",
- "layer": "A technical layer.",
- "lifecycle": "A lifecycle phase (``PLANNED|plan``, ``INTEGRATION|int``, ``PRODUCTION|prod``, ``END_OF_LIFE|eol|end``).",
- "note": "A custom note.",
- "scale": "Number of instances.",
- "security": "Description of the item's security status.",
- "shortname": "Abbreviated name.",
- "software": "Software/OS name.",
- "stability": "Description of the item's stability.",
- "team": "Name of the responsible team (e.g. technical owner).",
- "version": "The version (e.g. software version or protocol version).",
- "visibility": "Visibility to other items.",
- "weight": "Importance or relations. Used as factor for drawn width if numbers between 0 and 5 are given."
-}
+{"capability":"The capability the service provides for the business or, in case of infrastructure, the technical capability like enabling service discovery, configuration, secrets, or persistence.","color":"A hex color code (items inherit group colors as default)","costs":"Running costs of the item.","fill":"Background image (for displaying purposes).","frameworks":"A comma-separated list of frameworks as key-value pairs (key is name, value is version).","health":"Description of the item's health status.","icon":"Icon/image (for displaying purposes).","label":"A custom label (like a note, but very short).","layer":"A technical layer.","lifecycle":"A lifecycle phase (``PLANNED|plan``, ``INTEGRATION|int``, ``PRODUCTION|prod``, ``END_OF_LIFE|eol|end``).","note":"A custom note.","scale":"Number of instances.","security":"Description of the item's security status.","shortname":"Abbreviated name.","software":"Software/OS name.","stability":"Description of the item's stability.","team":"Name of the responsible team (e.g. technical owner).","version":"The version (e.g. software version or protocol version).","visibility":"Visibility to other items.","weight":"Importance or relations. Used as factor for drawn width if numbers between 0 and 5 are given."}
\ No newline at end of file
diff --git a/src/main/app/src/utils/testing/LandscapeContextValue.ts b/src/main/app/src/utils/testing/LandscapeContextValue.ts
index 180593997..fae362ab4 100644
--- a/src/main/app/src/utils/testing/LandscapeContextValue.ts
+++ b/src/main/app/src/utils/testing/LandscapeContextValue.ts
@@ -1,4 +1,11 @@
-import { IAssessment, IChanges, IGroup, IItem, ILandscape } from "../../interfaces";
+import {
+ IAssessment,
+ IChanges,
+ IGroup,
+ IItem,
+ ILandscape,
+ INotificationMessage,
+} from '../../interfaces';
import { LandscapeContextType } from '../../Context/LandscapeContext';
const items: IItem[] = [
@@ -15,6 +22,7 @@ const items: IItem[] = [
tags: [],
type: 'service',
icon: '',
+ networks: [],
},
];
@@ -24,6 +32,7 @@ const groups: IGroup[] = [
name: 'A Group',
items: items,
identifier: 'groupA',
+ icon: '',
},
];
@@ -69,16 +78,28 @@ const assessments: IAssessment = {
],
},
};
-
const changes: IChanges = {
-
-}
+ test: {
+ changeType: '',
+ componentType: '',
+ message: '',
+ },
+};
+const notification: INotificationMessage = {
+ timestamp: 'test',
+ landscape: 'test',
+ message: 'test',
+ level: 'success',
+ type: 'test',
+ date: new Date(),
+ changelog: { changes },
+};
const landscapeContextValue: LandscapeContextType = {
identifier: 'test',
landscape: landscape,
assessment: assessments,
- changes: changes,
+ changes: notification,
next: typeof jest != 'undefined' ? jest.fn() : () => {},
getAssessmentSummary: (fqi) => {
return assessments.results[fqi].find((assessmentResult) => assessmentResult.summary) || null;
diff --git a/src/main/app/yarn.lock b/src/main/app/yarn.lock
index 7e7b083a3..b24cbd62f 100644
--- a/src/main/app/yarn.lock
+++ b/src/main/app/yarn.lock
@@ -2193,10 +2193,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.24.tgz#b0f86f58564fa02a28b68f8b55d4cdec42e3b9d6"
integrity sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==
-"@types/node@^14.17.18":
- version "14.17.27"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.27.tgz#5054610d37bb5f6e21342d0e6d24c494231f3b85"
- integrity sha512-94+Ahf9IcaDuJTle/2b+wzvjmutxXAEXU6O81JHblYXUg2BDG+dnBy7VxIPHKAyEEDHzCMQydTJuWvrE+Aanzw==
+"@types/node@^14.17.29":
+ version "14.17.33"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.33.tgz#011ee28e38dc7aee1be032ceadf6332a0ab15b12"
+ integrity sha512-noEeJ06zbn3lOh4gqe2v7NMGS33jrulfNqYFDjjEbhpDEHR5VTxgYNQSBqBlJIsBJW3uEYDgD6kvMnrrhGzq8g==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@@ -2292,10 +2292,10 @@
"@types/prop-types" "*"
csstype "^3.0.2"
-"@types/react@^16.14.15":
- version "16.14.17"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.17.tgz#c57fcfb05efa6423f5b65fcd4a75f63f05b162bf"
- integrity sha512-pMLc/7+7SEdQa9A+hN9ujI8blkjFqYAZVqh3iNXqdZ0cQ8TIR502HMkNJniaOGv9SAgc47jxVKoiBJ7c0AakvQ==
+"@types/react@^16.14.20":
+ version "16.14.20"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.20.tgz#ff6e932ad71d92c27590e4a8667c7a53a7d0baad"
+ integrity sha512-SV7TaVc8e9E/5Xuv6TIyJ5VhQpZoVFJqX6IZgj5HZoFCtIDCArE3qXkcHlc6O/Ud4UwcMoX+tlvDA95YrKdLgA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
@@ -3893,9 +3893,9 @@ color-name@^1.0.0, color-name@~1.1.4:
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.5.2:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
- integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312"
+ integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
diff --git a/src/main/java/de/bonndan/nivio/input/ProcessingFinishedEvent.java b/src/main/java/de/bonndan/nivio/input/ProcessingFinishedEvent.java
index 1e3b78be3..75d429e23 100644
--- a/src/main/java/de/bonndan/nivio/input/ProcessingFinishedEvent.java
+++ b/src/main/java/de/bonndan/nivio/input/ProcessingFinishedEvent.java
@@ -1,6 +1,7 @@
package de.bonndan.nivio.input;
import de.bonndan.nivio.input.dto.LandscapeDescription;
+import de.bonndan.nivio.model.FullyQualifiedIdentifier;
import de.bonndan.nivio.model.Landscape;
import org.springframework.lang.NonNull;
@@ -65,4 +66,9 @@ public String getMessage() {
public ProcessingChangelog getChangelog() {
return changelog;
}
+
+ @Override
+ public FullyQualifiedIdentifier getSource() {
+ return landscape.getFullyQualifiedIdentifier();
+ }
}
diff --git a/src/main/java/de/bonndan/nivio/model/Item.java b/src/main/java/de/bonndan/nivio/model/Item.java
index a87f69491..34690f27b 100644
--- a/src/main/java/de/bonndan/nivio/model/Item.java
+++ b/src/main/java/de/bonndan/nivio/model/Item.java
@@ -320,6 +320,4 @@ public List getChanges(final Item newer) {
return changes;
}
-
-
}
\ No newline at end of file
diff --git a/src/main/java/de/bonndan/nivio/model/ItemFactory.java b/src/main/java/de/bonndan/nivio/model/ItemFactory.java
index 7700a20ed..a9fc93418 100644
--- a/src/main/java/de/bonndan/nivio/model/ItemFactory.java
+++ b/src/main/java/de/bonndan/nivio/model/ItemFactory.java
@@ -25,7 +25,7 @@ public static Item getTestItem(String group, String identifier) {
}
public static Item getTestItem(String group, String identifier, Landscape landscape) {
- return new Item(identifier, landscape, group, null,null,null,
+ return new Item(identifier, landscape, group, null, null, null,
null, null, null, null, null);
}
diff --git a/src/main/java/de/bonndan/nivio/output/docs/HtmlGenerator.java b/src/main/java/de/bonndan/nivio/output/docs/HtmlGenerator.java
index 49e5dbdc3..f8a5c9ca6 100644
--- a/src/main/java/de/bonndan/nivio/output/docs/HtmlGenerator.java
+++ b/src/main/java/de/bonndan/nivio/output/docs/HtmlGenerator.java
@@ -123,9 +123,9 @@ protected ContainerTag writeItem(Item item, Assessment assessment, Collection
join(
dt(FormatUtils.nice(
- statusItem.getField().endsWith("." + item.getIdentifier())
- ? statusItem.getField().replace("." + item.getIdentifier(), "")
- : statusItem.getField()
+ statusItem.getField().endsWith("." + item.getIdentifier())
+ ? statusItem.getField().replace("." + item.getIdentifier(), "")
+ : statusItem.getField()
) + " "
).with(
span(" " + statusItem.getStatus() + " ")
@@ -168,11 +168,11 @@ protected ContainerTag writeItem(Item item, Assessment assessment, Collection li(
+ item.getInterfaces().stream().filter(Objects::nonNull).map(interfaceItem -> li(
span(interfaceItem.getDescription()),
iff(StringUtils.hasLength(interfaceItem.getFormat()), span(", format: " + interfaceItem.getFormat())),
iff(interfaceItem.getUrl() != null && StringUtils.hasLength(interfaceItem.getUrl().toString()),
- span(", ").with(a(interfaceItem.getUrl().toString()).attr("href", interfaceItem.getUrl().toString()))
+ span(", ").with(a(String.valueOf(interfaceItem.getUrl())).attr("href", String.valueOf(interfaceItem.getUrl())))
)
))
))
diff --git a/src/main/java/de/bonndan/nivio/output/dto/ItemApiModel.java b/src/main/java/de/bonndan/nivio/output/dto/ItemApiModel.java
index f429e9216..76fb3b8a0 100644
--- a/src/main/java/de/bonndan/nivio/output/dto/ItemApiModel.java
+++ b/src/main/java/de/bonndan/nivio/output/dto/ItemApiModel.java
@@ -110,4 +110,8 @@ public String toString() {
return getFullyQualifiedIdentifier().toString();
}
+ public String[] getNetworks() {
+ return item.getLabels(Label.network).values().toArray(new String[0]);
+ }
+
}
diff --git a/src/main/java/de/bonndan/nivio/output/icons/IconCannotBeLoadedException.java b/src/main/java/de/bonndan/nivio/output/icons/IconCannotBeLoadedException.java
new file mode 100644
index 000000000..4474060b6
--- /dev/null
+++ b/src/main/java/de/bonndan/nivio/output/icons/IconCannotBeLoadedException.java
@@ -0,0 +1,8 @@
+package de.bonndan.nivio.output.icons;
+
+public class IconCannotBeLoadedException extends RuntimeException {
+
+ public IconCannotBeLoadedException(String errorMessage) {
+ super(errorMessage);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/bonndan/nivio/output/icons/IconMapping.java b/src/main/java/de/bonndan/nivio/output/icons/IconMapping.java
index 722d7f43e..eec1d46e9 100644
--- a/src/main/java/de/bonndan/nivio/output/icons/IconMapping.java
+++ b/src/main/java/de/bonndan/nivio/output/icons/IconMapping.java
@@ -19,6 +19,7 @@ public class IconMapping {
private static final Logger LOGGER = LoggerFactory.getLogger(IconMapping.class);
public static final String DEFAULT_ICON = "cog";
+ public static final String DEFAULT_GROUP_ICON = "hexagon-multiple-outline";
public static final String BACKEND = "backend";
public static final String CACHE = "cache";
diff --git a/src/main/java/de/bonndan/nivio/output/icons/IconService.java b/src/main/java/de/bonndan/nivio/output/icons/IconService.java
index 19da35e68..172437eec 100644
--- a/src/main/java/de/bonndan/nivio/output/icons/IconService.java
+++ b/src/main/java/de/bonndan/nivio/output/icons/IconService.java
@@ -12,8 +12,6 @@
/**
* Provides the builtin icons (shipped with nivio) and vendor icons (loaded form remote locations) as embeddable data.
- *
- *
*/
@Service
public class IconService {
@@ -53,7 +51,7 @@ public String getIconUrl(Item item) {
}
Optional iconUrl = localIcons.getIconUrl(icon);
- if(iconUrl.isPresent()) {
+ if (iconUrl.isPresent()) {
if (iconUrl.get().startsWith("http")) {
try {
return externalIcons.getUrl(new URL(iconUrl.get())).orElse(iconUrl.get());
diff --git a/src/main/java/de/bonndan/nivio/output/icons/LocalIcons.java b/src/main/java/de/bonndan/nivio/output/icons/LocalIcons.java
index 5da505ad5..356a8daec 100644
--- a/src/main/java/de/bonndan/nivio/output/icons/LocalIcons.java
+++ b/src/main/java/de/bonndan/nivio/output/icons/LocalIcons.java
@@ -13,6 +13,7 @@
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
+import static de.bonndan.nivio.output.icons.IconMapping.DEFAULT_GROUP_ICON;
import static de.bonndan.nivio.output.icons.IconMapping.DEFAULT_ICON;
/**
@@ -21,7 +22,7 @@
public class LocalIcons {
private static final Logger LOGGER = LoggerFactory.getLogger(LocalIcons.class);
- private static final String initErrorMsg = "Default icon could not be loaded from icon set folder %s." +
+ private static final String INIT_ERROR_MSG = "Default icon could not be loaded from icon set folder %s." +
" Make sure all npm dependencies are installed (or run mvn package).";
public static final String DEFAULT_ICONS_FOLDER = "/static/icons/svg/";
@@ -30,6 +31,8 @@ public class LocalIcons {
*/
private final String defaultIcon;
+ private final String defaultGroupIcon;
+
private final String iconFolder;
/**
@@ -49,8 +52,13 @@ public LocalIcons(@NonNull final String iconFolder) {
this.iconFolder = DEFAULT_ICONS_FOLDER;
}
defaultIcon = getIconUrl(DEFAULT_ICON).orElseThrow(() -> {
- throw new RuntimeException(String.format(initErrorMsg, this.iconFolder));
+ throw new IconCannotBeLoadedException(String.format(INIT_ERROR_MSG, this.iconFolder));
+ });
+
+ defaultGroupIcon = getIconUrl(DEFAULT_GROUP_ICON).orElseThrow(() -> {
+ throw new IconCannotBeLoadedException(String.format(INIT_ERROR_MSG, this.iconFolder));
});
+
}
public LocalIcons() {
@@ -86,6 +94,10 @@ public String getDefaultIcon() {
return defaultIcon;
}
+ public String getDefaultGroupIcon() {
+ return defaultGroupIcon;
+ }
+
/**
* Creates a SVG data url from the given resource path. Is cached.
*
diff --git a/src/main/java/de/bonndan/nivio/output/layout/AppearanceProcessor.java b/src/main/java/de/bonndan/nivio/output/layout/AppearanceProcessor.java
index 56fd96d30..764ad4905 100644
--- a/src/main/java/de/bonndan/nivio/output/layout/AppearanceProcessor.java
+++ b/src/main/java/de/bonndan/nivio/output/layout/AppearanceProcessor.java
@@ -1,10 +1,8 @@
package de.bonndan.nivio.output.layout;
-import de.bonndan.nivio.model.Item;
-import de.bonndan.nivio.model.Label;
-import de.bonndan.nivio.model.Labeled;
-import de.bonndan.nivio.model.Landscape;
+import de.bonndan.nivio.model.*;
import de.bonndan.nivio.output.icons.IconService;
+import de.bonndan.nivio.output.icons.LocalIcons;
import de.bonndan.nivio.util.URLHelper;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
@@ -26,13 +24,13 @@ public AppearanceProcessor(IconService iconService) {
public void process(@NonNull final Landscape landscape) {
Objects.requireNonNull(landscape).getGroupItems().forEach(group -> {
- setIconFillAppearance(group);
- landscape.getItems().retrieve(group.getItems()).forEach(this::setIconFillAppearance);
+ setIconAndFillAppearance(group);
+ landscape.getItems().retrieve(group.getItems()).forEach(this::setIconAndFillAppearance);
});
- setIconFillAppearance(landscape);
+ setIconAndFillAppearance(landscape);
}
- private void setIconFillAppearance(Labeled labeled) {
+ private void setIconAndFillAppearance(Labeled labeled) {
if (labeled instanceof Item) {
labeled.setLabel(Label._icondata, iconService.getIconUrl((Item) labeled));
@@ -43,6 +41,10 @@ private void setIconFillAppearance(Labeled labeled) {
.flatMap(iconService::getExternalUrl)
.ifPresent(s -> labeled.setLabel(Label._icondata, s));
}
+ if (!StringUtils.hasLength(icon) && labeled instanceof Group) {
+ LocalIcons localIcons = new LocalIcons();
+ labeled.setLabel(Label._icondata, localIcons.getDefaultGroupIcon());
+ }
}
String fill = labeled.getLabel(Label.fill);
diff --git a/src/main/java/de/bonndan/nivio/util/IconCannotBeLoadedException.java b/src/main/java/de/bonndan/nivio/util/IconCannotBeLoadedException.java
new file mode 100644
index 000000000..5f36ae919
--- /dev/null
+++ b/src/main/java/de/bonndan/nivio/util/IconCannotBeLoadedException.java
@@ -0,0 +1,8 @@
+package de.bonndan.nivio.util;
+
+public class IconCannotBeLoadedException extends RuntimeException {
+
+ public IconCannotBeLoadedException(String errorMessage) {
+ super(errorMessage);
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/frontendMapping.yml b/src/main/resources/frontendMapping.yml
index 661e2d9be..91d991322 100644
--- a/src/main/resources/frontendMapping.yml
+++ b/src/main/resources/frontendMapping.yml
@@ -2,5 +2,8 @@ frontendmapping:
keys:
shortname: short name
END_OF_LIFE: end of life
+ PRODUCTION: production
+ INTEGRATION: integration
+ PLANNED: planned
descriptions:
END_OF_LIFE: An end-of-life product is a product at the end of the product lifecycle which prevents users from receiving updates, indicating that the product is at the end of its useful life.
\ No newline at end of file
diff --git a/src/test/java/de/bonndan/nivio/model/ItemTest.java b/src/test/java/de/bonndan/nivio/model/ItemTest.java
index e83146a46..59fdd3bc5 100644
--- a/src/test/java/de/bonndan/nivio/model/ItemTest.java
+++ b/src/test/java/de/bonndan/nivio/model/ItemTest.java
@@ -1,6 +1,5 @@
package de.bonndan.nivio.model;
-import de.bonndan.nivio.input.kubernetes.InputFormatHandlerKubernetes;
import de.bonndan.nivio.assessment.Assessable;
import org.junit.jupiter.api.Test;
@@ -11,7 +10,8 @@
import static de.bonndan.nivio.model.ItemFactory.getTestItem;
import static de.bonndan.nivio.model.ItemFactory.getTestItemBuilder;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
class ItemTest {
@@ -54,7 +54,6 @@ void equalsWithLandscape() {
}
-
@Test
void getChangesInLabels() {
Landscape landscape = LandscapeFactory.createForTesting("l1", "l1Landscape").build();
diff --git a/src/test/java/de/bonndan/nivio/output/dto/ItemApiModelTest.java b/src/test/java/de/bonndan/nivio/output/dto/ItemApiModelTest.java
index 9e73dda44..0cd8ffd4e 100644
--- a/src/test/java/de/bonndan/nivio/output/dto/ItemApiModelTest.java
+++ b/src/test/java/de/bonndan/nivio/output/dto/ItemApiModelTest.java
@@ -97,7 +97,7 @@ void getName() {
Item s1 = itemTemplate.build();
ItemApiModel itemApiModel = new ItemApiModel(s1, group);
assertThat(itemApiModel.getColor()).isEqualTo(group.getColor());
- assertThat(itemApiModel.getName()).isEqualTo("");
+ assertThat(itemApiModel.getName()).isEmpty();
}
@Test
@@ -189,4 +189,11 @@ void testToString() {
assertThat(itemApiModel.getColor()).isEqualTo(group.getColor());
assertThat(itemApiModel.toString()).hasToString("l1/g1/a");
}
+
+ @Test
+ void getNetworks() {
+ Item s1 = itemTemplate.build();
+ ItemApiModel itemApiModel = new ItemApiModel(s1, group);
+ assertThat(itemApiModel.getNetworks()).isEqualTo(new String[0]);
+ }
}
\ No newline at end of file
diff --git a/src/test/java/de/bonndan/nivio/output/icons/LocalIconsTest.java b/src/test/java/de/bonndan/nivio/output/icons/LocalIconsTest.java
index fa13e0339..e686d645d 100644
--- a/src/test/java/de/bonndan/nivio/output/icons/LocalIconsTest.java
+++ b/src/test/java/de/bonndan/nivio/output/icons/LocalIconsTest.java
@@ -1,13 +1,17 @@
package de.bonndan.nivio.output.icons;
+import org.junit.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Base64;
import java.util.Optional;
+import static de.bonndan.nivio.output.icons.IconMapping.DEFAULT_GROUP_ICON;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
class LocalIconsTest {
@@ -47,4 +51,15 @@ void returnsDefault() {
void returnsTypeIgnoreCase() {
assertThat(localIcons.getIconUrl("AccOunT")).isNotEmpty();
}
+
+ @Test
+ void returnsGroupDefault() {
+ String icon = localIcons.getDefaultGroupIcon();
+ assertThat(icon).isNotEmpty();
+
+ String payload = icon.replace(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64, "");
+ String decoded = new String(Base64.getDecoder().decode(payload));
+ assertThat(decoded).contains("xml");
+ }
+
}
\ No newline at end of file
diff --git a/src/test/java/de/bonndan/nivio/output/layout/AppearanceProcessorTest.java b/src/test/java/de/bonndan/nivio/output/layout/AppearanceProcessorTest.java
index 4eb98985c..889c165ab 100644
--- a/src/test/java/de/bonndan/nivio/output/layout/AppearanceProcessorTest.java
+++ b/src/test/java/de/bonndan/nivio/output/layout/AppearanceProcessorTest.java
@@ -3,6 +3,7 @@
import de.bonndan.nivio.model.*;
import de.bonndan.nivio.output.icons.DataUrlHelper;
import de.bonndan.nivio.output.icons.IconService;
+import de.bonndan.nivio.output.icons.LocalIcons;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -10,12 +11,10 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Set;
import static de.bonndan.nivio.model.ItemFactory.getTestItem;
import static de.bonndan.nivio.model.ItemFactory.getTestItemBuilder;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -24,6 +23,7 @@ class AppearanceProcessorTest {
private AppearanceProcessor resolver;
private Landscape landscape;
private IconService iconService;
+ private LocalIcons localIcons;
private Group g1;
private ArrayList- items;
@@ -31,6 +31,7 @@ class AppearanceProcessorTest {
public void setup() {
iconService = mock(IconService.class);
+ localIcons = mock(LocalIcons.class);
landscape = LandscapeFactory.createForTesting("l1", "l1Landscape").build();
resolver = new AppearanceProcessor(iconService);
@@ -54,7 +55,7 @@ public void setup() {
}
@Test
- void setItemIcons_LabelIcon() {
+ void item_icon_setIconAndFillAppearance() {
Item s1 = landscape.getItems().pick("s1", "g1");
s1.setLabel(Label.icon, "https://dedica.team/images/logo_orange_weiss.png");
when(iconService.getIconUrl(s1)).thenReturn(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64 + "foo");
@@ -67,7 +68,7 @@ void setItemIcons_LabelIcon() {
}
@Test
- void setItemIcons_LabelFill() throws MalformedURLException {
+ void item_fill_setIconAndFillAppearance() throws MalformedURLException {
Item s1 = landscape.getItems().pick("s1", "g1");
s1.setLabel(Label.fill, "http://dedica.team/images/portrait.jpeg");
when(iconService.getExternalUrl(new URL(s1.getLabel(Label.fill)))).thenReturn(java.util.Optional.of(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64 + "foo"));
@@ -80,7 +81,7 @@ void setItemIcons_LabelFill() throws MalformedURLException {
}
@Test
- void setLandscapeIcons_LabelIcon() throws MalformedURLException {
+ void landscape_icon_setIconAndFillAppearance() throws MalformedURLException {
// given
landscape.setLabel(Label.icon, "https://dedica.team/images/logo_orange_weiss.png");
@@ -94,7 +95,7 @@ void setLandscapeIcons_LabelIcon() throws MalformedURLException {
}
@Test
- void setLandscapeIcons_LabelFill() throws MalformedURLException {
+ void landscape_fill_setIconAndFillAppearance() throws MalformedURLException {
// given
landscape.setLabel(Label.fill, "http://dedica.team/images/portrait.jpeg");
@@ -108,7 +109,7 @@ void setLandscapeIcons_LabelFill() throws MalformedURLException {
}
@Test
- void setGroupIcons_LabelIcon() throws MalformedURLException {
+ void group_icon_setIconAndFillAppearance() throws MalformedURLException {
// given
g1.setLabel(Label.icon, "https://dedica.team/images/logo_orange_weiss.png");
@@ -122,7 +123,7 @@ void setGroupIcons_LabelIcon() throws MalformedURLException {
}
@Test
- void setGroupIcons_LabelFill() throws MalformedURLException {
+ void group_fill_setIconAndFillAppearance() throws MalformedURLException {
// given
g1.setLabel(Label.fill, "http://dedica.team/images/portrait.jpeg");
@@ -135,4 +136,18 @@ void setGroupIcons_LabelFill() throws MalformedURLException {
assertThat(g1.getLabel(Label._filldata)).isEqualTo(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64 + "foo");
}
+ @Test
+ void group_setDefaultIcon_setIconAndFillAppearance() {
+
+ // given
+ // default group icon
+ when(localIcons.getDefaultGroupIcon()).thenReturn(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64 + "PD94bWwg");
+
+ // when
+ resolver.process(landscape);
+
+ // then
+ assertThat(g1.getIcon()).startsWith(DataUrlHelper.DATA_IMAGE_SVG_XML_BASE_64 + "PD94bWwg");
+ }
+
}
\ No newline at end of file
diff --git a/src/test/java/de/bonndan/nivio/util/FrontendMappingTest.java b/src/test/java/de/bonndan/nivio/util/FrontendMappingTest.java
index 14d421912..f6bb2d07c 100644
--- a/src/test/java/de/bonndan/nivio/util/FrontendMappingTest.java
+++ b/src/test/java/de/bonndan/nivio/util/FrontendMappingTest.java
@@ -24,8 +24,8 @@ class FrontendMappingTest {
@Test
@Order(1)
void getKeys() {
- var testMap = Map.of("shortname", "short name", "END_OF_LIFE", "end of life");
- assertThat(frontendMapping.getKeys()).isEqualTo(testMap);
+ assertThat(frontendMapping.getKeys()).containsEntry("END_OF_LIFE", "end of life");
+ assertThat(frontendMapping.getKeys()).containsEntry("shortname", "short name");
}
@Test
diff --git a/src/test/resources/example/dedica.dot b/src/test/resources/example/dedica.dot
index a272ddf67..b3b2c2aab 100644
--- a/src/test/resources/example/dedica.dot
+++ b/src/test/resources/example/dedica.dot
@@ -47,14 +47,14 @@ digraph G {
nivio_name = "Daniel Brünker",
nivio_contact= "daniel.bruenker@dedica.team",
nivio_group= dedica
- nivio_fill= "http://dedica.team/images/danielbruenker.jpeg"
+ nivio_fill= "https://dedica.team/images/danielbruenker.jpeg"
]
jennifer [
nivio_name = "Jennifer Arps",
nivio_contact= "jennifer@dedica.team",
nivio_group= dedica
- nivio_fill= "http://dedica.team/images/jenniferarps.jpeg"
+ nivio_fill= "https://dedica.team/images/jenniferarps.jpg"
]
dedica -> matthias [nivio_type = provider]
@@ -62,5 +62,7 @@ digraph G {
dedica -> jan [nivio_type = provider]
dedica -> michelle [nivio_type = provider]
dedica -> marvin [nivio_type = provider]
+ dedica -> daniel2 [nivio_type = provider]
+ dedica -> jennifer [nivio_type = provider]
}
\ No newline at end of file
diff --git a/src/test/resources/example/dedica.yml b/src/test/resources/example/dedica.yml
index c3d135298..77a4cfe8c 100644
--- a/src/test/resources/example/dedica.yml
+++ b/src/test/resources/example/dedica.yml
@@ -57,20 +57,20 @@ items:
- identifier: marvin
name: Marvin Schöning
group: dedica
- fill: http://dedica.team/images/marvinschoening.jpeg
+ fill: https://dedica.team/images/marvinschoening.jpeg
providedBy:
- dedica
- identifier: daniel2
name: Daniel Brünker
group: dedica
- fill: http://dedica.team/images/danielbruenker.jpeg
+ fill: https://dedica.team/images/danielbruenker.jpeg
providedBy:
- dedica
- identifier: jennifer
name: Jennifer Arps
group: dedica
- fill: http://dedica.team/images/jenniferarps.jpeg
+ fill: https://dedica.team/images/jenniferarps.jpg
providedBy:
- dedica
\ No newline at end of file