Unverified Commit b1ad548f authored by Philipp Berger's avatar Philipp Berger
Browse files

chore: release v2.1.0

parent 7c538367
# Changelog
### 2.1.0 (2021-10-01)
* **backend** feat: add signed location transfer support
* **backend** feat: add average checkin time
* **backend** feat: add support route
* **backend** feat: delete redeemed vaccination certificates after 72 hours
* **backend:** fix: extend unique constraint for notification messages
* **backend:** fix: deletion of notification chunks
* **health-department** fix: check public HDSKP when uploading private key
* **health-department** fix: cursor did not change on hovering download options in contact person view
* **health-department** fix: update contact list when value changes for location tranfers
* **health-department** fix: warning in console concerning button properties
* **health-department** fix: remove default icon tooltip for notification
* **health-department** feat: sign share data requests to locations with HDSKP
* **health-department** feat: improve edit employee fields
* **health-department** feat: change menu button
* **health-department** feat: add 1.63.1 to supported SORMAS versions
* **locations** fix: timestamp in email for share data requests
* **locations** fix: limit traceId in guest list to seven characters
* **locations** fix: QR-Print instructions text and alignment
* **locations** fix: wrong time format in share data modal
* **locations** fix: make whole entry in dropdown menu clickable
* **locations** feat: venue owners can declare an average visit duration for their venue
* **locations** feat: new help center
* **locations** feat: user can choose to not load the Google Places API when creating locations
* **locations** feat: update privacy policy documents
* **locations** feat: update data processing agreement document
* **locations** feat: improve usablity of the dropdown to switch between locations
* **scanner** chore: integrate PO editor
* chore: enable static compression
### 2.0.2 (2021-09-15)
* **backend:** perf: add bloomfilter generation metrics
* **backend:** fix: set timezone via config
......@@ -194,7 +224,7 @@
* **health-department:** fix: order of locations changed after contacting venues
* **health-department:** feat: add hover effect to process list for better usability
* **health-department:** feat: new designs for location search
* **health-department:** feat: locations can be search by zip code as additional parameter to the location name
* **health-department:** feat: locations can be search by zip code as additional parameter to the location name
* **health-department:** feat: new designs for profile view
* **health-department:** feat: select profile view got moved from tab to header
* **health-department:** feat: improved locales
......@@ -281,7 +311,7 @@
* **health-department:** feat: include address information directly in contact person view and not only in the download files
* **health-department:** fix: dependency tree
* **scanner:** fix: update check ins counter after scanning badges
* **scanner:** fix: refocus after outbounds clicks in hardware scanner
* **scanner:** fix: refocus after outbounds clicks in hardware scanner
* **webapp:** feat: support international phone numbers
* **webapp:** feat: handle unsupported deeplinks
......@@ -294,7 +324,7 @@
* **health-department:** fix: add more error handling in csv generation
### 1.1.13 (2021-05-26)
* **health-department:** fix: whitlisted special characters for csv
* **health-department:** fix: whitlisted special characters for csv
### 1.1.12 (2021-05-26)
* **health-department:** fix: csv sanitization
......
......@@ -4,6 +4,8 @@ services:
image: lucaapp/elb:${IMAGE_TAG}
build:
context: "services/elb"
args:
ENABLED_MODULES: brotli
ports:
- 80:8080
- 443:8443
......
......@@ -15,11 +15,12 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/downloads/
/downloads
tsconfig.json
cypress/fixtures
cypress/screenshots
cypress/plugins/downloads
# certificates
certs/*.pfx
\ No newline at end of file
{
"baseUrl": "https://localhost",
"projectId": "9qr32w",
"testFiles": "**/*.spec.js",
"testFiles": [
"workflow/**/*.spec.js",
"webapp/**/*.spec.js",
"locations/downloadPDF/downloadPDF.spec.js",
"health-department/**/*.spec.js",
"scanner/**/*.spec.js",
"locations/authentication/**/*.spec.js",
"locations/checkinOptions/**/*.spec.js",
"locations/group/**/*.spec.js",
"locations/location/**/*.spec.js",
"locations/locationOverview/*.spec.js",
"locations/locationSettings/*.spec.js",
"locations/navigation/*.spec.js",
"locations/profile/*.spec.js"
],
"integrationFolder": "./specs",
"video": false,
"supportFile": "./support",
......
{
"name": "e2e",
"version": "2.0.2",
"version": "2.1.0",
"main": "index.js",
"private": true,
"engines": {
......
......@@ -28,7 +28,7 @@ describe('Autentication', () => {
);
cy.contains('Wrong Email or password').should('not.exist');
cy.url().should('include', '/app/tracking');
cy.get('.ant-modal').within($modal => {
cy.get('.ant-modal').within(() => {
cy.contains('Setup').should('exist');
cy.contains(
'The key file for this health department was generated. Please make sure to download the file and not to lose it. You will need it to decrypt the data from requested locations.'
......@@ -36,11 +36,13 @@ describe('Autentication', () => {
cy.getByCy('downloadPrivateKey').should('exist').should('be.enabled');
});
downloadHealthDepartmentPrivateKey();
cy.getByCy('header').within($header => {
cy.contains('Health-Department').should('exist').should('be.visible');
cy.get('.ant-dropdown-trigger').should('exist').should('be.enabled');
cy.get('button').contains('LOG OUT').should('exist');
});
cy.getByCy('header')
.contains('Health-Department')
.should('exist')
.should('be.visible');
cy.getByCy('linkMenu').should('exist').should('be.visible');
cy.get('button').contains('LOG OUT').should('exist');
cy.get('.ant-menu-horizontal').should('exist').should('be.visible');
cy.getByCy('navigation').should('exist').should('be.visible');
});
......
......@@ -62,15 +62,13 @@ describe('Authentication', () => {
it('it should reject the key upload and a notification should show stating that a wrong key has been uploaded, after that the correct private key is being uploaded and a notification occurs stating the the private key has been successfully uploaded as well the modal should close', () => {
testSetup();
uploadWrongHealthDepartmentPrivateKeyFileTypeReUploadCorrectFile();
cy.getByCy('header').within($header => {
cy.contains('Health-Department')
.should('exist')
.should('be.visible');
cy.get('.ant-dropdown-trigger')
.should('exist')
.should('be.enabled');
cy.get('button').contains('LOG OUT').should('exist');
});
cy.getByCy('header')
.contains('Health-Department')
.should('exist')
.should('be.visible');
cy.getByCy('linkMenu').should('exist').should('be.visible');
cy.get('button').contains('LOG OUT').should('exist');
cy.get('.ant-menu-horizontal').should('exist').should('be.visible');
cy.getByCy('navigation').should('exist').should('be.visible');
logout();
......
import { E2E_HEALTH_DEPARTMENT_USERNAME, E2E_HEALTH_DEPARTMENT_PASSWORD } from '../../helper/user';
import {
E2E_HEALTH_DEPARTMENT_USERNAME,
E2E_HEALTH_DEPARTMENT_PASSWORD,
} from '../../helper/user';
import { logout } from '../../helper/api/auth.helper';
import { loginToHD, openHDLoginPage, addHealthDepartmentPrivateKeyFile } from '../../helper/ui/login.helper';
import {
loginToHD,
openHDLoginPage,
addHealthDepartmentPrivateKeyFile,
} from '../../helper/ui/login.helper';
describe('Autentication', () => {
describe('Health Department / Authentication / Login', () => {
describe('when a user login for the second time', () => {
it('ask to upload private key and redirect to tracking page', () => {
openHDLoginPage();
loginToHD(E2E_HEALTH_DEPARTMENT_USERNAME, E2E_HEALTH_DEPARTMENT_PASSWORD);
loginToHD(
E2E_HEALTH_DEPARTMENT_USERNAME,
E2E_HEALTH_DEPARTMENT_PASSWORD
);
cy.contains('Wrong Email or password').should('not.exist');
cy.url().should('include', '/app/tracking');
addHealthDepartmentPrivateKeyFile();
cy.getByCy('header').within(($header) => {
cy.contains('Health-Department').should('exist').should('be.visible');
cy.get('.ant-dropdown-trigger').should('exist').should('be.enabled');
cy.get('button').contains('LOG OUT').should('exist');
});
cy.getByCy('header')
.contains('Health-Department')
.should('exist')
.should('be.visible');
cy.getByCy('linkMenu').should('exist').should('be.visible');
cy.get('button').contains('LOG OUT').should('exist');
cy.get('.ant-menu-horizontal').should('exist').should('be.visible');
cy.getByCy('navigation').should('exist').should('be.visible');
logout();
});
});
});
})
});
......@@ -5,7 +5,7 @@ describe('Logout', () => {
it('logs the user out', () => {
cy.getByCy('createGroup').should('exist');
cy.getByCy('dropdownMenuTrigger').click();
cy.getByCy('dropdownMenu').contains('Log out').click({ force: true });
cy.getByCy('logout').click();
cy.getByCy('loginPage').should('exist');
cy.get('#email').should('exist');
});
......
import { login } from '../helpers/functions';
import {
openCreateGroupModal,
selectGroupType,
setGroupName,
setGroupAddress,
setGroupPhone,
setGroupIndoorSelection,
} from '../helpers/createGroup.helper';
import {
RESTAURANT_ADDRESS,
RESTAURANT_NAME,
......@@ -16,16 +26,16 @@ describe('Download QR Codes PDF', { retries: 3 }, () => {
describe('On Group creation', () => {
it('downloads the Group PDF', () => {
cy.getByCy('createGroup').click();
cy.getByCy('restaurant').click();
cy.get('#groupName', { timeout: 20000 }).type(RESTAURANT_NAME);
cy.get('form').submit();
cy.get('#locationSearch').type(RESTAURANT_ADDRESS);
cy.get('.pac-container > div:first-of-type').click({ force: true });
openCreateGroupModal();
selectGroupType('restaurant');
setGroupName(RESTAURANT_NAME);
setGroupAddress(RESTAURANT_ADDRESS);
// Proceed
cy.getByCy('proceed').click();
cy.get('#phone').type(RESTAURANT_PHONE);
cy.get('form').submit();
cy.get('form').submit();
setGroupPhone(RESTAURANT_PHONE);
// Proceed by skipping average checkin time
cy.getByCy('nextStep').click();
setGroupIndoorSelection();
cy.getByCy('no').click();
cy.getByCy('no').click();
cy.getByCy('finishGroupCreation').click();
......@@ -52,6 +62,7 @@ describe('Download QR Codes PDF', { retries: 3 }, () => {
cy.getByCy('yes').click();
cy.get('#phone').type(RESTAURANT_PHONE);
cy.getByCy('nextStep').click();
cy.getByCy('nextStep').click();
cy.getByCy('indoorSelection').click();
cy.getByCy('selectIndoor').click();
cy.get('button[type=submit]').click();
......
import { login } from '../../helpers/functions';
import {
createGroup,
deleteGroup,
login,
logout,
resetGroups,
} from '../../helpers/functions';
import {
E2E_DEFAULT_LOCATION_GROUP,
E2E_LOCATION_GROUP_2,
E2E_DEFAULT_LOCATION_GROUP_2,
E2E_DEFAULT_GROUP_NAME,
E2E_GROUP_NAME_2,
} from '../../helpers/locations';
import { createGroupPayload } from '../../helpers/functions.helper';
const GROUPS = [
'Nexenio_3 e2e',
'Nexenio_4 e2e',
];
const GROUP_IDS = [];
describe('Change groups', () => {
before(() => {
login();
resetGroups();
logout();
});
beforeEach(() => login());
it('can change groups', () => {
cy.getByCy('groupName').should('contain', E2E_DEFAULT_GROUP_NAME);
cy.getByCy('selectGroupDropdown').click();
cy.getByCy(`groupItem-${E2E_LOCATION_GROUP_2}`).click();
cy.getByCy(`groupItem-${E2E_DEFAULT_LOCATION_GROUP_2}`).click();
cy.getByCy('groupName').should('contain', E2E_GROUP_NAME_2);
cy.getByCy('selectGroupDropdown').click();
cy.getByCy(`groupItem-${E2E_DEFAULT_LOCATION_GROUP}`).click();
cy.getByCy('groupName').should('contain', E2E_DEFAULT_GROUP_NAME);
});
describe('when searchable select is present', () => {
before(() => {
login();
GROUPS.forEach(group => {
createGroup({ ...createGroupPayload, name: group });
cy.get('@groupId').then(groupId => {
GROUP_IDS.push(groupId);
});
});
logout();
});
after(() => {
login();
GROUP_IDS.forEach(id => deleteGroup(id));
});
it('can change groups in select', () => {
cy.getByCy('groupName').should('contain', E2E_DEFAULT_GROUP_NAME);
cy.getByCy('selectGroupDropdown').click();
cy.getByCy('groupSelect').click();
cy.getByCy(`groupItem-${E2E_DEFAULT_LOCATION_GROUP_2}`).click();
cy.getByCy('groupName').should('contain', E2E_GROUP_NAME_2);
cy.getByCy('selectGroupDropdown').click();
cy.getByCy('groupSelect').click();
cy.getByCy(`groupItem-${E2E_DEFAULT_LOCATION_GROUP}`).click();
cy.getByCy('groupName').should('contain', E2E_DEFAULT_GROUP_NAME);
});
it('can search for groups', () => {
cy.getByCy('selectGroupDropdown').click();
cy.getByCy('groupSelect').type(`${E2E_GROUP_NAME_2}{enter}`);
cy.getByCy('groupName').should('contain', E2E_GROUP_NAME_2);
});
});
});
import { login } from '../../helpers/functions';
import { checkRadiusInput } from '../../helpers/inputValidation.helper';
import {
openCreateGroupModal,
selectGroupType,
setGroupName,
setGroupAddress,
setGroupPhone,
setGroupArea,
setGroupRadius,
checkForExistingFields,
checkForDisabledFields,
addressFields,
} from '../../helpers/createGroup.helper';
const HOTEL_NAME = 'Test Hotel';
const HOTEL_ADDRESS = 'Nexenio';
......@@ -14,51 +26,19 @@ describe('Group creation', () => {
beforeEach(() => login());
describe('Create hotel or base type', () => {
it('creates group of type hotel', { retries: 3 }, () => {
// Modal create group modal
cy.getByCy('createGroup').should('exist');
cy.getByCy('createGroup').click();
// Select hotel
cy.getByCy('hotel').click();
// Enter name
cy.get('#groupName').type(HOTEL_NAME);
// Proceed
cy.get('button[type=submit]').click();
// Enter location
cy.get('#locationSearch').type(HOTEL_ADDRESS);
// Select from googleApi
cy.get('.pac-container > div:first-of-type', { timeout: 6000 }).should(
'be.visible'
);
cy.get('.pac-container > div:first-of-type').click();
// Expect fields to be filled out and disabled
cy.get('#streetName').should('exist');
cy.get('#streetNr').should('exist');
cy.get('#zipCode').should('exist');
cy.get('#city').should('exist');
cy.get('#streetName').should('be.disabled');
cy.get('#streetNr').should('be.disabled');
cy.get('#zipCode').should('be.disabled');
cy.get('#city').should('be.disabled');
openCreateGroupModal();
selectGroupType('hotel');
setGroupName(HOTEL_NAME);
setGroupAddress(HOTEL_ADDRESS);
checkForExistingFields(addressFields);
checkForDisabledFields(addressFields);
// Proceed
cy.getByCy('proceed').click();
// Enter phone
cy.get('#phone').type(HOTEL_PHONE);
// Proceed
cy.get('button[type=submit]').click();
// Select more areas
cy.getByCy('yes').click();
cy.getByCy('areaNameInput').type(HOTEL_AREA);
cy.getByCy('indoorSelection').click();
cy.getByCy('selectIndoor').click();
// Proceed
cy.get('button[type=submit]').click();
// Select automatic checkout
cy.getByCy('yes').click();
// Enter radius
checkRadiusInput();
cy.get('#radius').clear().type(HOTEL_RADIUS);
// Proceed
cy.get('button[type=submit]').click();
setGroupPhone(HOTEL_PHONE);
// Proceed by skipping average checkin time
cy.getByCy('nextStep').click();
setGroupArea(HOTEL_AREA);
setGroupRadius(HOTEL_RADIUS);
// Create group
cy.getByCy('finishGroupCreation').click();
// No qr download
......@@ -70,49 +50,19 @@ describe('Group creation', () => {
cy.contains('#groupList', HOTEL_AREA);
});
it('creates group of type base', { retries: 3 }, () => {
// Modal create group modal
cy.getByCy('createGroup').should('exist');
cy.getByCy('createGroup').click();
// Select base
cy.getByCy('base').click();
// Enter name
cy.get('#groupName').type(BASE_NAME);
// Proceed
cy.get('button[type=submit]').click();
// Enter location
cy.get('#locationSearch').type(HOTEL_ADDRESS);
// Select from googleApi
cy.get('.pac-container > div:first-of-type').should('be.visible');
cy.get('.pac-container > div:first-of-type').click();
// Expect fields to be filled out and disabled
cy.get('#streetName').should('exist');
cy.get('#streetNr').should('exist');
cy.get('#zipCode').should('exist');
cy.get('#city').should('exist');
cy.get('#streetName').should('be.disabled');
cy.get('#streetNr').should('be.disabled');
cy.get('#zipCode').should('be.disabled');
cy.get('#city').should('be.disabled');
openCreateGroupModal();
selectGroupType('base');
setGroupName(BASE_NAME);
setGroupAddress(HOTEL_ADDRESS);
checkForExistingFields(addressFields);
checkForDisabledFields(addressFields);
// Proceed
cy.getByCy('proceed').click();
// Enter phone
cy.get('#phone').type(HOTEL_PHONE);
// Proceed
cy.get('button[type=submit]').click();
// Select more areas
cy.getByCy('yes').click();
cy.getByCy('areaNameInput').type(BASE_AREA);
cy.getByCy('indoorSelection').click();
cy.getByCy('selectIndoor').click();
// Proceed
cy.get('button[type=submit]').click();
// Select automatic checkout
cy.getByCy('yes').click();
// Enter radius
checkRadiusInput();
cy.get('#radius').clear().type(HOTEL_RADIUS);
// Proceed
cy.get('button[type=submit]').click();
setGroupPhone(HOTEL_PHONE);
// Proceed by skipping average checkin time
cy.getByCy('nextStep').click();
setGroupArea(BASE_AREA);
setGroupRadius(HOTEL_RADIUS);
// Create group
cy.getByCy('finishGroupCreation').click();
// No qr download
......
import { login } from '../../helpers/functions';
import { checkRadiusInput } from '../../helpers/inputValidation.helper';
import {
openCreateGroupModal,
selectGroupType,
setGroupName,
setGroupAddress,
setGroupPhone,
setGroupRadius,
checkForExistingFields,
checkForDisabledFields,
addressFields,
} from '../../helpers/createGroup.helper';
const NURSING_HOME_NAME = 'Test Nursing Home';
const NURSING_HOME_ADDRESS = 'Nexenio';
......@@ -9,44 +20,20 @@ describe('Group creation', () => {
beforeEach(() => login());
describe('Create Nursing Home', () => {
it('creates group of type nursing_home', { retries: 3 }, () => {
// Modal create group modal
cy.getByCy('createGroup').should('exist');
cy.getByCy('createGroup').click();
// Select nursing home
cy.getByCy('nursing_home').click();
// Enter name
cy.get('#groupName').type(NURSING_HOME_NAME);
// Proceed
cy.get('button[type=submit]').click();
// Enter location
cy.get('#locationSearch').type(NURSING_HOME_ADDRESS);
// Select from googleApi
cy.get('.pac-container > div:first-of-type').should('be.visible');
cy.get('.pac-container > div:first-of-type').click();
// Expect fields to be filled out and disabled
cy.get('#streetName').should('exist');
cy.get('#streetNr').should('exist');
cy.get('#zipCode').should('exist');
cy.get('#city').should('exist');
cy.get('#streetName').should('be.disabled');
cy.get('#streetNr').should('be.disabled');
cy.get('#zipCode').should('be.disabled');
cy.get('#city').should('be.disabled');
openCreateGroupModal();
selectGroupType('nursing_home');
setGroupName(NURSING_HOME_NAME);
setGroupAddress(NURSING_HOME_ADDRESS);
checkForExistingFields(addressFields);
checkForDisabledFields(addressFields);
// Proceed
cy.getByCy('proceed').click();
// Enter phone
cy.get('#phone').type(NURSING_HOME_PHONE);
// Proceed
cy.get('button[type=submit]').click();
setGroupPhone(NURSING_HOME_PHONE);
// Proceed by skipping average checkin time
cy.getByCy('nextStep').click();
// Select post checkin questions
cy.getByCy('yes').click();
// Select automatic checkout
cy.getByCy('yes').click();
// Enter radius
checkRadiusInput();
cy.get('#radius').clear().type(NURSING_HOME_RADIUS);
// Proceed
cy.get('button[type=submit]').click();
setGroupRadius(NURSING_HOME_RADIUS);
// Create group
cy.getByCy('finishGroupCreation').click();
// No qr download
......
import { login } from '../../helpers/functions';
import { checkRadiusInput } from '../../helpers/inputValidation.helper';