Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1609: Enable store import koblenz #1655

Merged
merged 9 commits into from
Oct 14, 2024

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions administration/resources/stores/sample_stores.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name,street,houseNumber,postalCode,location,latitude,longitude,telephone,email,homepage,discountDE,discountEN,categoryId
Test Ballett et Danse,Teststr.,10,90408,Nürnberg,49.4622598,11.0765467,0911/123456,[email protected],https://www.test.de/kontakt/,20% Ermäßigung für Erwachsene,20% discount for adults,17
Apotheke,Test Str.,187,90429,Nürnberg,49.4565929,11.0365767,0911/323213123,[email protected],https://www.apotheke-nuernberg.de,"10 % Ermäßigung auf nicht verschreibungspflichtige Medikamente, die die Kasse nicht bezahlt („grüne Rezepte“). Außer Angebotspreise",10% discount on non-prescription medicine that is not covered by health insurance (“green prescriptions”). Except special offers,15
Shop,Test-Henlein-Str.,27,90443,Nürnberg,49.441456,11.0740208,0911/12340,[email protected],https://www.afbshop.de/nuernberg,"10% Ermäßigung für PC, Notebooks (gebraucht mit Garantie)","10% discount for PC, notebooks (used with warranty)",16
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name,street,houseNumber,postalCode,location,latitude,longitude,telephone,email,homepage,discountDE,discountEN,categoryId
Test Ballett et Danse,Teststr.,10,90408,Nürnberg,49.4622598,11.0765467,0911/123456,[email protected],https://www.test.de/kontakt/,20% Ermäßigung für Erwachsene,20% discount for adults,17
Apotheke,Fürther Str.,187,90429,Nürnberg,,,0911/323213123,[email protected],https://www.apotheke-nuernberg.de,"10 % Ermäßigung auf nicht verschreibungspflichtige Medikamente, die die Kasse nicht bezahlt („grüne Rezepte“). Außer Angebotspreise",10% discount on non-prescription medicine that is not covered by health insurance (“green prescriptions”). Except special offers,15
Shop,Test-Henlein-Str.,27,90443,Nürnberg,49.441456,11.0740208,0911/12340,[email protected],https://www.afbshop.de/nuernberg,"10% Ermäßigung für PC, Notebooks (gebraucht mit Garantie)","10% discount for PC, notebooks (used with warranty)",16
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import { LOCAL_STORAGE_PROJECT_KEY } from '../../../project-configs/constants'
import koblenzConfig from '../../../project-configs/koblenz/config'
import nuernbergConfig from '../../../project-configs/nuernberg/config'
import { AcceptingStoreEntry } from '../AcceptingStoreEntry'
import { invalidStoreData, validStoreData } from '../__mock__/mockStoreEntry'

const fields = nuernbergConfig.storeManagement.enabled ? nuernbergConfig.storeManagement.fields : []
describe('AcceptanceStoreEntry', () => {
it('should be validated false store invalid entries', () => {
const store = new AcceptingStoreEntry(invalidStoreData, fields)
expect(store.isValid()).toBeFalsy()
})
it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
`should be validated false store invalid entries for $projectConfig.name`,
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const fields = projectConfig.storeManagement.enabled ? projectConfig.storeManagement.fields : []
const store = new AcceptingStoreEntry(invalidStoreData, fields)
expect(store.isValid()).toBeFalsy()
}
)

it('should be validated true store valid entries', () => {
const store = new AcceptingStoreEntry(validStoreData, fields)
expect(store.isValid()).toBeTruthy()
})
it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
'should be validated true store valid entries $projectConfig.name',
({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const fields = projectConfig.storeManagement.enabled ? projectConfig.storeManagement.fields : []
const store = new AcceptingStoreEntry(validStoreData, fields)
expect(store.isValid()).toBeTruthy()
}
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { act, fireEvent, render } from '@testing-library/react'
import { ReactElement } from 'react'

import { ProjectConfigProvider } from '../../../project-configs/ProjectConfigContext'
import { LOCAL_STORAGE_PROJECT_KEY } from '../../../project-configs/constants'
import koblenzConfig from '../../../project-configs/koblenz/config'
import nuernbergConfig from '../../../project-configs/nuernberg/config'
import { AcceptingStoreEntry } from '../AcceptingStoreEntry'
import StoresButtonBar from '../StoresButtonBar'
Expand All @@ -16,93 +18,121 @@ const importStores = jest.fn()
const wrapper = ({ children }: { children: ReactElement }) => <ProjectConfigProvider>{children}</ProjectConfigProvider>

describe('StoresButtonBar', () => {
it('Should goBack when clicking back', async () => {
const { getByText } = render(
<StoresButtonBar dryRun setDryRun={setDryRun} goBack={goBack} acceptingStores={[]} importStores={importStores} />,
{
wrapper,
}
)

const backButton = getByText('Zurück zur Auswahl')
expect(backButton).toBeTruthy()

fireEvent.click(backButton)
await act(async () => null) // Popper update() - https://github.com/popperjs/react-popper/issues/350

expect(goBack).toHaveBeenCalled()
})

it('Should disable import button for no stores', async () => {
const { getByText } = render(
<StoresButtonBar dryRun setDryRun={setDryRun} goBack={goBack} acceptingStores={[]} importStores={importStores} />,
{
wrapper,
}
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
expect(importButton.disabled).toBeTruthy()
fireEvent.mouseOver(importButton)
fireEvent.click(importButton)
await act(async () => {
jest.advanceTimersByTime(100)
})

expect(getByText('Laden sie bitte eine Datei mit Akzeptanzpartnern hoch.')).toBeTruthy()
expect(importStores).not.toHaveBeenCalled()
})

it('Should disable import stores for invalid store entries', async () => {
const fields = nuernbergConfig.storeManagement.enabled ? nuernbergConfig.storeManagement.fields : []
const stores = [new AcceptingStoreEntry(invalidStoreData, fields)]
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={stores}
importStores={importStores}
/>,
{ wrapper }
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
fireEvent.mouseOver(importButton)
fireEvent.click(importButton)

await act(async () => {
jest.advanceTimersByTime(100)
})

expect(importButton.disabled).toBeTruthy()
expect(getByText('Fehlerhafte Einträge. Bitte prüfen sie die rot markierten Felder.')).toBeTruthy()
expect(importStores).not.toHaveBeenCalled()
})

it('Should import valid stores', async () => {
const fields = nuernbergConfig.storeManagement.enabled ? nuernbergConfig.storeManagement.fields : []
const stores = [new AcceptingStoreEntry(validStoreData, fields)]
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={stores}
importStores={importStores}
/>,
{ wrapper }
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
fireEvent.click(importButton)
const importConfirmationButton = getByText('Stores importieren').closest('button') as HTMLButtonElement
fireEvent.click(importConfirmationButton)
await act(async () => null) // Popper update() - https://github.com/popperjs/react-popper/issues/350

expect(importStores).toHaveBeenCalled()
})
it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
`Should goBack when clicking back for $projectConfig.name`,
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
async ({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={[]}
importStores={importStores}
/>,
{
wrapper,
}
)

const backButton = getByText('Zurück zur Auswahl')
expect(backButton).toBeTruthy()

fireEvent.click(backButton)
await act(async () => null) // Popper update() - https://github.com/popperjs/react-popper/issues/350

expect(goBack).toHaveBeenCalled()
}
)

it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
`Should disable import button for no stores for $projectConfig.name`,
async ({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={[]}
importStores={importStores}
/>,
{
wrapper,
}
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
expect(importButton.disabled).toBeTruthy()
fireEvent.mouseOver(importButton)
fireEvent.click(importButton)
await act(async () => {
jest.advanceTimersByTime(100)
})

expect(getByText('Laden sie bitte eine Datei mit Akzeptanzpartnern hoch.')).toBeTruthy()
expect(importStores).not.toHaveBeenCalled()
}
)

it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
`Should disable import stores for invalid store entries for $projectConfig.name`,
async ({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const fields = projectConfig.storeManagement.enabled ? projectConfig.storeManagement.fields : []
const stores = [new AcceptingStoreEntry(invalidStoreData, fields)]
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={stores}
importStores={importStores}
/>,
{ wrapper }
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
fireEvent.mouseOver(importButton)
fireEvent.click(importButton)

await act(async () => {
jest.advanceTimersByTime(100)
})

expect(importButton.disabled).toBeTruthy()
expect(getByText('Fehlerhafte Einträge. Bitte prüfen sie die rot markierten Felder.')).toBeTruthy()
expect(importStores).not.toHaveBeenCalled()
}
)

it.each([{ projectConfig: nuernbergConfig }, { projectConfig: koblenzConfig }])(
`Should import valid stores for $projectConfig.name`,
async ({ projectConfig }) => {
localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, projectConfig.projectId)
const fields = projectConfig.storeManagement.enabled ? projectConfig.storeManagement.fields : []
const stores = [new AcceptingStoreEntry(validStoreData, fields)]
const { getByText } = render(
<StoresButtonBar
dryRun
setDryRun={setDryRun}
goBack={goBack}
acceptingStores={stores}
importStores={importStores}
/>,
{ wrapper }
)

const importButton = getByText('Import Stores').closest('button') as HTMLButtonElement
expect(importButton).toBeTruthy()
fireEvent.click(importButton)
const importConfirmationButton = getByText('Stores importieren').closest('button') as HTMLButtonElement
fireEvent.click(importConfirmationButton)
await act(async () => null) // Popper update() - https://github.com/popperjs/react-popper/issues/350

expect(importStores).toHaveBeenCalled()
}
)
})
5 changes: 2 additions & 3 deletions administration/src/project-configs/koblenz/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import BirthdayExtension from '../../cards/extensions/BirthdayExtension'
import RegionExtension from '../../cards/extensions/RegionExtension'
import StartDayExtension from '../../cards/extensions/StartDayExtension'
import { ProjectConfig } from '../getProjectConfig'
import { storeConfig } from '../storeConfig'
import { DataPrivacyBaseText, dataPrivacyBaseHeadline } from './dataPrivacyBase'
import pdfConfig from './pdf'

Expand All @@ -26,9 +27,7 @@ const config: ProjectConfig = {
cardStatistics: { enabled: false },
freinetCSVImportEnabled: false,
cardCreation: false,
storeManagement: {
enabled: false,
},
storeManagement: storeConfig,
userImportApiEnabled: true,
}

Expand Down
2 changes: 1 addition & 1 deletion administration/src/project-configs/nuernberg/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import NuernbergPassIdExtension from '../../cards/extensions/NuernbergPassIdExte
import RegionExtension from '../../cards/extensions/RegionExtension'
import StartDayExtension from '../../cards/extensions/StartDayExtension'
import { ProjectConfig } from '../getProjectConfig'
import { storeConfig } from '../storeConfig'
import ActivityLogEntry from './ActivityLogEntry'
import { buildCsvLine } from './csvExport'
import { DataPrivacyBaseText, dataPrivacyBaseHeadline } from './dataPrivacyBase'
import pdfConfig from './pdf'
import { storeConfig } from './storeConfig'

const config: ProjectConfig = {
name: 'Digitaler Nürnberg-Pass',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { buildConfigNuernberg } from 'build-configs'

import { getBuildConfig } from '../util/getBuildConfig'
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
import {
FIELD_HOUSE_NUMBER,
FIELD_LATITUDE,
Expand All @@ -8,14 +7,14 @@ import {
FIELD_NAME,
FIELD_POSTAL_CODE,
FIELD_STREET,
} from '../constants'
import { StoresManagement } from '../getProjectConfig'
} from './constants'
import { StoresManagement } from './getProjectConfig'
import {
hasMandatoryValue,
hasValidCategoryId,
isCoordinate,
noValidationRequired,
} from '../helper/storeFieldValidation'
} from './helper/storeFieldValidation'

export const storeConfig: StoresManagement = {
f1sh1918 marked this conversation as resolved.
Show resolved Hide resolved
enabled: true,
Expand All @@ -35,7 +34,7 @@ export const storeConfig: StoresManagement = {
{
name: 'categoryId',
isMandatory: true,
isValid: category => hasValidCategoryId(category, buildConfigNuernberg.common.categories),
isValid: category => hasValidCategoryId(category, getBuildConfig(window.location.hostname).common.categories),
columnWidth: 100,
},
],
Expand Down
6 changes: 6 additions & 0 deletions administration/src/util/getBuildConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
BAYERN_PRODUCTION_ID,
BAYERN_STAGING_ID,
BuildConfigType,
KOBLENZ_PRODUCTION_ID,
KOBLENZ_STAGING_ID,
NUERNBERG_PRODUCTION_ID,
NUERNBERG_STAGING_ID,
buildConfigBayern,
Expand All @@ -18,6 +20,10 @@ export const getBuildConfig = (hostname: string): BuildConfigType => {
case NUERNBERG_PRODUCTION_ID:
case NUERNBERG_STAGING_ID:
return buildConfigNuernberg
case KOBLENZ_PRODUCTION_ID:
case KOBLENZ_STAGING_ID:
// TODO 1647 Add correct buildConfig for koblenz
return buildConfigNuernberg
default:
console.debug('Falling back to bayern.')
return buildConfigBayern
Expand Down