diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml deleted file mode 100644 index e1d296746..000000000 --- a/.github/workflows/trivy.yml +++ /dev/null @@ -1,53 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: trivy - -on: - push: - branches: [ "devel" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "devel" ] - # schedule: - # - cron: '44 1 * * 3' - -permissions: - contents: read - -jobs: - build: - permissions: - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status - name: Build - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Scan repository with Trivy - uses: aquasecurity/trivy-action@0.20.0 - with: - scan-type: fs - ignore-unfixed: true - format: 'sarif' - limit-severities-for-sarif: true #By default SARIF format enforces output of all vulnerabilities. To override this behavior set this parameter to true - severity: 'HIGH,CRITICAL' - output: trivy-results.sarif - skip-dirs: docs - continue-on-error: true # still upload SARIF even if vulnerabilities exist - - - name: Debug SARIF - run: | - head -n 20 trivy-results.sarif - jq .version trivy-results.sarif - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: trivy-results.sarif - # Optional category for the results - # Used to differentiate multiple results for one commit diff --git a/Makefile b/Makefile index 429a0fa4c..fcc6ee389 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ wheel-devel: clean fi; \ echo "Version $$BUILD_VER"; \ poetry install --no-root --with devel; \ - poetry run python3 -m build -w + poetry run python3.12 -m build -w mv -f dist/*.whl . diff --git a/docker/collectstatic.sh b/docker/collectstatic.sh index ae39132f5..b35289c22 100755 --- a/docker/collectstatic.sh +++ b/docker/collectstatic.sh @@ -2,5 +2,5 @@ . /opt/poem/bin/activate rm -rf $VIRTUAL_ENV/usr/share/poem/static/reactbundle/* ; \ -python $VIRTUAL_ENV/lib/python3.9/site-packages/Poem/manage.py collectstatic --noinput ; \ +python $VIRTUAL_ENV/lib/python3.12/site-packages/Poem/manage.py collectstatic --noinput ; \ rm -rf $VIRTUAL_ENV/usr/share/poem/static/admin diff --git a/etc/poem.auto.conf.template b/etc/poem.auto.conf.template new file mode 100644 index 000000000..ef839159d --- /dev/null +++ b/etc/poem.auto.conf.template @@ -0,0 +1,9 @@ +[GENERAL_TENANTNAME] +# Extra tenant GENERAL options may be defined here. + +[SUPERUSER_TENANTNAME] +# Extra tenant SUPERUSER options may be defined here. + +[SECURITY] +# AllowedHosts values are appended to SECURITY.AllowedHosts from poem.conf. +AllowedHosts = diff --git a/poem/Poem/api/internal_views/app.py b/poem/Poem/api/internal_views/app.py index a89a6bc19..721a360b6 100644 --- a/poem/Poem/api/internal_views/app.py +++ b/poem/Poem/api/internal_views/app.py @@ -1,4 +1,4 @@ -import configparser +from configparser import NoOptionError, NoSectionError from Poem.api import serializers from Poem.api.internal_views.users import get_all_groups, get_groups_for_user @@ -110,8 +110,7 @@ def get(self, request, istenant): def get_use_service_titles(tenant): - config = configparser.ConfigParser() - config.read(filenames=settings.CONFIG_FILE) + config = settings.GET_POEM_CONFIG(settings.CONFIG_FILE) try: if config.get( @@ -122,7 +121,7 @@ def get_use_service_titles(tenant): else: return False - except configparser.NoOptionError: + except (NoOptionError, NoSectionError): return False diff --git a/poem/Poem/frontend/react/__tests__/MetricProfiles.test.js b/poem/Poem/frontend/react/__tests__/MetricProfiles.test.js index 3c07cf974..d05c6adce 100644 --- a/poem/Poem/frontend/react/__tests__/MetricProfiles.test.js +++ b/poem/Poem/frontend/react/__tests__/MetricProfiles.test.js @@ -697,6 +697,17 @@ function renderCloneView(combined=false) { } +async function selectMetricProfileTuple(row, service, metric) { + await selectEvent.select(row.getAllByText("Select...")[0], service) + + await waitFor(() => { + expect(row.getByText(service)).toBeInTheDocument() + }) + + await selectEvent.select(row.getAllByText("Select...")[0], metric) +} + + function renderVersionDetailsView() { const route = '/ui/metricprofiles/TEST_PROFILE/history/20201214-085323'; @@ -832,7 +843,7 @@ describe('Tests for metric profiles changeview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).not.toBeInTheDocument() expect(screen.queryByLabelText(/profile/i)).not.toBeInTheDocument() @@ -890,7 +901,7 @@ describe('Tests for metric profiles changeview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).not.toBeInTheDocument() expect(screen.queryByLabelText(/profile/i)).not.toBeInTheDocument() @@ -1203,13 +1214,7 @@ describe('Tests for metric profiles changeview', () => { expect(row7.getByText("Central-LFC")).toBeInTheDocument() expect(row7.getByText("ch.cern.LFC-Write")).toBeInTheDocument() - await waitFor(() => { - selectEvent.select(row5.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row5.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row5, "eu.argo.ams", "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1271,12 +1276,7 @@ describe('Tests for metric profiles changeview', () => { expect(row8.getByText("Central-LFC")).toBeInTheDocument() expect(row8.getByText("ch.cern.LFC-Write")).toBeInTheDocument() - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "Central-LFC") - }) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "ch.cern.LFC-Write") - }) + await selectMetricProfileTuple(row2, "Central-LFC", "ch.cern.LFC-Write") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).toBeInTheDocument() @@ -1322,21 +1322,13 @@ describe('Tests for metric profiles changeview', () => { expect(row8.getByText("Central-LFC")).toBeInTheDocument() expect(row8.getByText("ch.cern.LFC-Read")).toBeInTheDocument() - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "Central-LFC") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "ch.cern.LFC-Write") - }) + await selectMetricProfileTuple(row2, "Central-LFC", "ch.cern.LFC-Write") await waitFor(() => { expect(screen.queryAllByText(/duplicated/i)).toHaveLength(2) }) - await waitFor(() => { - selectEvent.select(row2.getByText("ch.cern.LFC-Write"), "argo.AMS-Check") - }) + await selectEvent.select(row2.getByText("ch.cern.LFC-Write"), "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1443,7 +1435,7 @@ describe('Tests for metric profiles changeview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(nameField.value).toBe('ARGO_MON'); expect(nameField).toBeDisabled(); @@ -1505,7 +1497,7 @@ describe('Tests for metric profiles changeview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(nameField.value).toBe('ARGO_MON'); expect(nameField).toBeDisabled(); @@ -1579,12 +1571,7 @@ describe('Tests for metric profiles changeview', () => { const rows = metricInstances.getAllByRole('row'); const row4 = within(rows[6]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "org.opensciencegrid.htcondorce") - }) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "ch.cern.HTCondorCE-JobState") - }) + await selectMetricProfileTuple(row4, "org.opensciencegrid.htcondorce", "ch.cern.HTCondorCE-JobState") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1626,26 +1613,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1739,26 +1714,14 @@ describe('Tests for metric profiles changeview', () => { const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1856,25 +1819,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(metricInstances.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -1987,26 +1939,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2121,26 +2061,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2252,26 +2180,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2386,26 +2302,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2528,26 +2432,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2670,26 +2562,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2807,26 +2687,14 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -2968,13 +2836,7 @@ describe('Tests for metric profiles changeview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -3052,13 +2914,7 @@ describe('Tests for metric profiles changeview', () => { rows = metricInstances.getAllByRole("row") const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "ARC-CE") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row2, "ARC-CE", "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -3537,8 +3393,8 @@ describe('Tests for metric profile addview', () => { expect(screen.queryByText('ARGO')).not.toBeInTheDocument() expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('ARGO')).toBeInTheDocument() - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('ARGO')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).not.toBeInTheDocument() expect(screen.queryByLabelText(/profile/i)).not.toBeInTheDocument() @@ -3574,8 +3430,8 @@ describe('Tests for metric profile addview', () => { expect(screen.queryByText('ARGO')).not.toBeInTheDocument() expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('ARGO')).toBeInTheDocument() - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('ARGO')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).toBeInTheDocument() expect(screen.queryAllByLabelText(/profile/i)).toHaveLength(2) @@ -3645,8 +3501,7 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole("row") var row1 = within(rows[2]) - await selectEvent.select(row1.getAllByText("Select...")[0], "argo.mon") - await selectEvent.select(row1.getAllByText("Select...")[0], "eu.egi.CertValidity") + await selectMetricProfileTuple(row1, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -3664,13 +3519,7 @@ describe('Tests for metric profile addview', () => { expect(rows).toHaveLength(4) var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row2, "eu.argo.ams", "argo.AMS-Check") rows = metricInstances.getAllByRole("row") expect(rows).toHaveLength(4) @@ -3691,13 +3540,7 @@ describe('Tests for metric profile addview', () => { expect(rows).toHaveLength(5) var row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row3, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { expect(screen.queryAllByText(/duplicated/i)).toHaveLength(2) @@ -3946,13 +3789,7 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); const row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row2, "eu.argo.ams", "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -4140,50 +3977,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4278,50 +4091,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4419,50 +4208,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4568,50 +4333,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4717,50 +4458,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4861,50 +4578,26 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); var row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); var row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -4995,51 +4688,27 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(screen.getByTestId('remove-3')); @@ -5109,52 +4778,28 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -5241,52 +4886,28 @@ describe('Tests for metric profile addview', () => { const row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(metricInstances.getByTestId('remove-3')); @@ -5382,52 +5003,28 @@ describe('Tests for metric profile addview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[2]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(metricInstances.getByTestId('insert-0')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row3 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row3.getAllByText("Select...")[1], "argo.AMSPublisher-Check") - }) + await selectMetricProfileTuple(row3, "eu.argo.ams", "argo.AMSPublisher-Check") fireEvent.click(screen.getByTestId('insert-2')); rows = metricInstances.getAllByRole('row'); const row4 = within(rows[5]) - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[0], "argo.mon") - }) - - await waitFor(() => { - selectEvent.select(row4.getAllByText("Select...")[1], "eu.egi.CertValidity") - }) + await selectMetricProfileTuple(row4, "argo.mon", "eu.egi.CertValidity") await waitFor(() => { fireEvent.click(screen.getByTestId('remove-3')); @@ -5538,7 +5135,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).not.toBeInTheDocument() expect(screen.queryByLabelText(/profile/i)).not.toBeInTheDocument() @@ -5598,7 +5195,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText('TEST')).not.toBeInTheDocument() selectEvent.openMenu(groupField) - expect(screen.getByText('TEST')).toBeInTheDocument() + expect(await screen.findByText('TEST')).toBeInTheDocument() expect(screen.queryByText("Combined from")).not.toBeInTheDocument() expect(screen.queryByLabelText(/profile/i)).not.toBeInTheDocument() @@ -5683,6 +5280,13 @@ describe('Tests for metric profile cloneview', () => { }) const metricInstances = within(screen.getByRole("table")) + let rows + const waitForRows = async length => { + await waitFor(() => { + rows = metricInstances.getAllByRole("row") + expect(rows).toHaveLength(length) + }) + } fireEvent.click(screen.getByTestId("remove-2")) @@ -5690,8 +5294,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() }) - var rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(8) + await waitForRows(8) var row1 = within(rows[2]) var row2 = within(rows[3]) var row3 = within(rows[4]) @@ -5717,8 +5320,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() }) - rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(9) + await waitForRows(9) row1 = within(rows[2]) row2 = within(rows[3]) row3 = within(rows[4]) @@ -5740,20 +5342,13 @@ describe('Tests for metric profile cloneview', () => { expect(row7.getByText("Central-LFC")).toBeInTheDocument() expect(row7.getByText("ch.cern.LFC-Write")).toBeInTheDocument() - await waitFor(() => { - selectEvent.select(row5.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row5.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row5, "eu.argo.ams", "argo.AMS-Check") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() }) - rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(9) + await waitForRows(9) row1 = within(rows[2]) row2 = within(rows[3]) row3 = within(rows[4]) @@ -5782,8 +5377,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() }) - rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(10) + await waitForRows(10) row1 = within(rows[2]) row2 = within(rows[3]) row3 = within(rows[4]) @@ -5808,13 +5402,7 @@ describe('Tests for metric profile cloneview', () => { expect(row8.getByText("Central-LFC")).toBeInTheDocument() expect(row8.getByText("ch.cern.LFC-Write")).toBeInTheDocument() - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "Central-LFC") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "ch.cern.LFC-Write") - }) + await selectMetricProfileTuple(row2, "Central-LFC", "ch.cern.LFC-Write") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).toBeInTheDocument() @@ -5828,8 +5416,7 @@ describe('Tests for metric profile cloneview', () => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() }) - rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(9) + await waitForRows(9) row1 = within(rows[2]) row2 = within(rows[3]) row3 = within(rows[4]) @@ -5880,8 +5467,7 @@ describe('Tests for metric profile cloneview', () => { fireEvent.click(screen.getByTestId("remove-0")) }) - rows = metricInstances.getAllByRole("row") - expect(rows).toHaveLength(3) + await waitForRows(3) row1 = within(rows[2]) expect(row1.getAllByText("Select...")).toHaveLength(2) }) @@ -5921,26 +5507,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6065,26 +5639,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6212,26 +5774,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6367,26 +5917,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6522,26 +6060,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6672,26 +6198,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6811,26 +6325,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -6924,26 +6426,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -7053,26 +6543,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -7197,26 +6675,14 @@ describe('Tests for metric profile cloneview', () => { var rows = metricInstances.getAllByRole('row'); const row1 = within(rows[3]) - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[0], "eu.argo.ams") - }) - - await waitFor(() => { - selectEvent.select(row1.getAllByText("Select...")[1], "argo.AMS-Check") - }) + await selectMetricProfileTuple(row1, "eu.argo.ams", "argo.AMS-Check") fireEvent.click(screen.getByTestId('insert-1')); rows = metricInstances.getAllByRole('row'); const row2 = within(rows[4]) - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[0], "egi.AppDB") - }) - - await waitFor(() => { - selectEvent.select(row2.getAllByText("Select...")[1], "org.nagiosexchange.AppDB-WebCheck") - }) + await selectMetricProfileTuple(row2, "egi.AppDB", "org.nagiosexchange.AppDB-WebCheck") await waitFor(() => { expect(screen.queryByText(/duplicated/i)).not.toBeInTheDocument() @@ -7354,4 +6820,4 @@ describe('Test for metric profile version detail page', () => { expect(screen.queryByRole('button', { name: /clone/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /csv/i })).not.toBeInTheDocument(); }) -}) \ No newline at end of file +}) diff --git a/poem/Poem/frontend/react/__tests__/Probes.test.js b/poem/Poem/frontend/react/__tests__/Probes.test.js index f8856663c..25a7db2df 100644 --- a/poem/Poem/frontend/react/__tests__/Probes.test.js +++ b/poem/Poem/frontend/react/__tests__/Probes.test.js @@ -612,10 +612,10 @@ describe('Test probe changeview on SuperAdmin POEM', () => { expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).not.toBeInTheDocument() expect(screen.queryByText('nagios-plugins-http (present)')).not.toBeInTheDocument() selectEvent.openMenu(packageField) - expect(screen.queryByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-http (present)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-http (present)')).toBeInTheDocument() expect(metricLinks[0].closest('a')).toHaveAttribute('href', '/ui/metrictemplates/argo.AMS-Check'); expect(metricLinks[1].closest('a')).toHaveAttribute('href', '/ui/metrictemplates/test.AMS-Check'); @@ -1083,11 +1083,11 @@ describe('Test probe addview', () => { expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).not.toBeInTheDocument() expect(screen.queryByText('nagios-plugins-http (present)')).not.toBeInTheDocument() selectEvent.openMenu(packageField) - expect(screen.queryByText('nagios-plugins-argo (0.1.11)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-http (present)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-argo (0.1.11)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-http (present)')).toBeInTheDocument() expect(screen.queryByRole('button', { name: /clone/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /history/i })).not.toBeInTheDocument(); @@ -1341,10 +1341,10 @@ describe('Test probe cloneview', () => { expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).not.toBeInTheDocument() expect(screen.queryByText('nagios-plugins-http (present)')).not.toBeInTheDocument() selectEvent.openMenu(packageField) - expect(screen.queryByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() - expect(screen.queryByText('nagios-plugins-http (present)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-argo (0.1.12)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-fedcloud (0.5.0)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-globus (0.1.5)')).toBeInTheDocument() + expect(await screen.findByText('nagios-plugins-http (present)')).toBeInTheDocument() expect(screen.queryByRole('button', { name: /clone/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /history/i })).not.toBeInTheDocument(); diff --git a/poem/Poem/frontend/react/__tests__/YumRepos.test.js b/poem/Poem/frontend/react/__tests__/YumRepos.test.js index d2cea32f1..a2797fa19 100644 --- a/poem/Poem/frontend/react/__tests__/YumRepos.test.js +++ b/poem/Poem/frontend/react/__tests__/YumRepos.test.js @@ -358,7 +358,7 @@ describe('Tests for YUM repos changeview on SuperAdmin POEM', () => { expect(screen.queryByText('CentOS 7')).not.toBeInTheDocument() selectEvent.openMenu(tagField) - expect(screen.getByText('CentOS 7')).toBeInTheDocument() + expect(await screen.findByText('CentOS 7')).toBeInTheDocument() expect(contentField.value).toBe('[argo-devel]\nname=ARGO Product Repository\nbaseurl=http://rpm-repo.argo.grnet.gr/ARGO/devel/centos6/\ngpgcheck=0enabled=1\npriority=99\nexclude=\nincludepkgs=') expect(contentField).toBeEnabled(); @@ -691,8 +691,8 @@ describe('Tests for YUM repo addview', () => { expect(screen.queryByText('CentOS 6')).not.toBeInTheDocument() expect(screen.queryByText('CentOS 7')).not.toBeInTheDocument() selectEvent.openMenu(tagField) - expect(screen.getByText('CentOS 6')).toBeInTheDocument() - expect(screen.getByText('CentOS 7')).toBeInTheDocument() + expect(await screen.findByText('CentOS 6')).toBeInTheDocument() + expect(await screen.findByText('CentOS 7')).toBeInTheDocument() expect(contentField.value).toBe(''); expect(contentField).toBeEnabled(); @@ -874,7 +874,7 @@ describe('Tests for YUM repo cloneview', () => { expect(screen.queryByText('CentOS 7')).not.toBeInTheDocument() selectEvent.openMenu(tagField) - expect(screen.getByText('CentOS 7')).toBeInTheDocument() + expect(await screen.findByText('CentOS 7')).toBeInTheDocument() expect(contentField.value).toBe('[argo-devel]\nname=ARGO Product Repository\nbaseurl=http://rpm-repo.argo.grnet.gr/ARGO/devel/centos6/\ngpgcheck=0enabled=1\npriority=99\nexclude=\nincludepkgs=') expect(contentField).toBeEnabled(); diff --git a/poem/Poem/poem/management/commands/poem_create_tenant.py b/poem/Poem/poem/management/commands/poem_create_tenant.py index fc6773719..dd9eeb07e 100644 --- a/poem/Poem/poem/management/commands/poem_create_tenant.py +++ b/poem/Poem/poem/management/commands/poem_create_tenant.py @@ -1,5 +1,3 @@ -from configparser import ConfigParser - from Poem.poem import models as poem_models from Poem.tenants.models import Tenant from django.conf import settings @@ -41,8 +39,7 @@ def create_tenant(name, hostname, combined=False): def get_public_schema_hostname(): - config = ConfigParser() - config.read(settings.CONFIG_FILE) + config = settings.GET_POEM_CONFIG() hostname = config.get('GENERAL_ALL', 'publicpage') diff --git a/poem/Poem/poem/management/commands/poem_superuser.py b/poem/Poem/poem/management/commands/poem_superuser.py index 17c58e828..5a6fad7cc 100644 --- a/poem/Poem/poem/management/commands/poem_superuser.py +++ b/poem/Poem/poem/management/commands/poem_superuser.py @@ -1,4 +1,4 @@ -from configparser import ConfigParser, NoSectionError, NoOptionError +from configparser import NoSectionError, NoOptionError from Poem.poem.models import UserProfile from django.conf import settings @@ -12,8 +12,7 @@ def tenant_superuser(): tenant = connection.tenant.name - config = ConfigParser() - config.read(settings.CONFIG_FILE) + config = settings.GET_POEM_CONFIG() superuser_name = config.get('SUPERUSER_' + tenant.upper(), 'name') superuser_pass = config.get('SUPERUSER_' + tenant.upper(), 'password') diff --git a/poem/Poem/poem/saml2/config.py b/poem/Poem/poem/saml2/config.py index d0e85aec8..1ba5a10a6 100644 --- a/poem/Poem/poem/saml2/config.py +++ b/poem/Poem/poem/saml2/config.py @@ -1,8 +1,6 @@ import sysconfig import saml2 -from configparser import ConfigParser - from saml2.config import SPConfig from django.conf import settings @@ -24,17 +22,15 @@ def get_hostname(request): def service_name_conf(tenant): - config = ConfigParser() - config.read(settings.CONFIG_FILE) - - return config.get('GENERAL_' + tenant.upper(), 'samlservicename') + return settings.GET_POEM_CONFIG().get( + 'GENERAL_' + tenant.upper(), 'samlservicename' + ) def saml_login_string(tenant): - config = ConfigParser() - config.read(settings.CONFIG_FILE) - - return config.get('GENERAL_' + tenant.upper(), 'samlloginstring') + return settings.GET_POEM_CONFIG().get( + 'GENERAL_' + tenant.upper(), 'samlloginstring' + ) def get_saml_config(request): diff --git a/poem/Poem/settings-devserver.py b/poem/Poem/settings-devserver.py index 38c834134..2f5457ca0 100644 --- a/poem/Poem/settings-devserver.py +++ b/poem/Poem/settings-devserver.py @@ -6,13 +6,63 @@ VENV = '/opt/poem' APP_PATH = os.path.abspath(os.path.split(__file__)[0]) CONFIG_FILE = '{}/etc/poem/poem.conf'.format(VENV) +AUTO_CONFIG_FILE = '{}/etc/poem/poem.auto.conf'.format(VENV) LOG_CONFIG = '{}/etc/poem/poem_logging.conf'.format(VENV) -try: + +def _split_comma_list(value): + return [item.strip() for item in value.split(',') if item.strip()] + + +def _merge_auto_config(config, auto_config_file=AUTO_CONFIG_FILE): + auto_config = ConfigParser() + + if not auto_config.read([auto_config_file]): + return + + for option, value in auto_config.defaults().items(): + config['DEFAULT'][option] = value + + for section in auto_config.sections(): + if not config.has_section(section): + config.add_section(section) + + for option, value in auto_config._sections[section].items(): + if option == '__name__': + continue + + if ( + section == 'SECURITY' and + option.lower() == 'allowedhosts' and + config.has_option(section, option) + ): + allowed_hosts = _split_comma_list( + config.get(section, option, raw=True) + ) + allowed_hosts.extend(_split_comma_list(value)) + config.set(section, option, ', '.join(allowed_hosts)) + + else: + config.set(section, option, value) + + +def get_poem_config(config_file=None, auto_config_file=None): + config_file = config_file or CONFIG_FILE + auto_config_file = auto_config_file or AUTO_CONFIG_FILE + config = ConfigParser() - if not config.read([CONFIG_FILE]): - raise ImproperlyConfigured('Unable to parse config file %s' % CONFIG_FILE) + if not config.read([config_file]): + raise ImproperlyConfigured('Unable to parse config file %s' % config_file) + + _merge_auto_config(config, auto_config_file) + return config + + +try: + config = get_poem_config() + GET_POEM_CONFIG = get_poem_config + POEM_CONFIG = config # General DEBUG = bool(config.getboolean('GENERAL', 'debug')) diff --git a/poem/Poem/settings.py b/poem/Poem/settings.py index f00a7186d..83fb78ef6 100644 --- a/poem/Poem/settings.py +++ b/poem/Poem/settings.py @@ -6,13 +6,63 @@ VENV = '/opt/poem' APP_PATH = os.path.abspath(os.path.split(__file__)[0]) CONFIG_FILE = '{}/etc/poem/poem.conf'.format(VENV) +AUTO_CONFIG_FILE = '{}/etc/poem/poem.auto.conf'.format(VENV) LOG_CONFIG = '{}/etc/poem/poem_logging.conf'.format(VENV) -try: + +def _split_comma_list(value): + return [item.strip() for item in value.split(',') if item.strip()] + + +def _merge_auto_config(config, auto_config_file=AUTO_CONFIG_FILE): + auto_config = ConfigParser() + + if not auto_config.read([auto_config_file]): + return + + for option, value in auto_config.defaults().items(): + config['DEFAULT'][option] = value + + for section in auto_config.sections(): + if not config.has_section(section): + config.add_section(section) + + for option, value in auto_config._sections[section].items(): + if option == '__name__': + continue + + if ( + section == 'SECURITY' and + option.lower() == 'allowedhosts' and + config.has_option(section, option) + ): + allowed_hosts = _split_comma_list( + config.get(section, option, raw=True) + ) + allowed_hosts.extend(_split_comma_list(value)) + config.set(section, option, ', '.join(allowed_hosts)) + + else: + config.set(section, option, value) + + +def get_poem_config(config_file=None, auto_config_file=None): + config_file = config_file or CONFIG_FILE + auto_config_file = auto_config_file or AUTO_CONFIG_FILE + config = ConfigParser() - if not config.read([CONFIG_FILE]): - raise ImproperlyConfigured('Unable to parse config file %s' % CONFIG_FILE) + if not config.read([config_file]): + raise ImproperlyConfigured('Unable to parse config file %s' % config_file) + + _merge_auto_config(config, auto_config_file) + return config + + +try: + config = get_poem_config() + GET_POEM_CONFIG = get_poem_config + POEM_CONFIG = config # General DEBUG = bool(config.getboolean('GENERAL', 'debug')) @@ -85,7 +135,6 @@ else: ALLOWED_HOSTS = [ALLOWED_HOSTS] - # Make this unique, and don't share it with anybody. try: SECRET_KEY = open(SECRETKEY_PATH, 'r').read() diff --git a/poem/Poem/webpack.config.js b/poem/Poem/webpack.config.js index 5e12e0e5c..bfa11ae21 100644 --- a/poem/Poem/webpack.config.js +++ b/poem/Poem/webpack.config.js @@ -24,7 +24,10 @@ module.exports = { } }, plugins: [ - new BundleTracker({filename: './webpack-stats.json'}), + new BundleTracker({ + filename: 'webpack-stats.json', + path: path.resolve(process.cwd()) + }) ], module: { rules: [ diff --git a/poem/Poem/webpack.devserver.config.js b/poem/Poem/webpack.devserver.config.js index 0a3635fb7..0afdf7fa4 100644 --- a/poem/Poem/webpack.devserver.config.js +++ b/poem/Poem/webpack.devserver.config.js @@ -18,8 +18,9 @@ module.exports = { }, plugins: [ new BundleTracker({ - filename: 'webpack-stats.json' - }), + filename: 'webpack-stats.json', + path: path.resolve(process.cwd()) + }) ], module: { rules: [