diff --git a/src/backend/InvenTree/InvenTree/serializers.py b/src/backend/InvenTree/InvenTree/serializers.py index bd348c9b07..386a373b8b 100644 --- a/src/backend/InvenTree/InvenTree/serializers.py +++ b/src/backend/InvenTree/InvenTree/serializers.py @@ -768,6 +768,9 @@ class ContentTypeField(serializers.ChoiceField): content_type = None + if data in ['', None]: + return None + # First, try to resolve the content type via direct pk value try: content_type_id = int(data) diff --git a/src/frontend/tests/pui_settings.spec.ts b/src/frontend/tests/pui_settings.spec.ts index 52361ab0bd..fbdd590b6c 100644 --- a/src/frontend/tests/pui_settings.spec.ts +++ b/src/frontend/tests/pui_settings.spec.ts @@ -254,7 +254,7 @@ test('Settings - Admin', async ({ browser }) => { await loadTab(page, 'Currencies'); await loadTab(page, 'Project Codes'); await loadTab(page, 'Custom Units'); - await loadTab(page, 'Part Parameters'); + await loadTab(page, 'Parameters', true); await loadTab(page, 'Category Parameters'); await loadTab(page, 'Label Templates'); await loadTab(page, 'Report Templates'); @@ -373,6 +373,115 @@ test('Settings - Admin - Barcode History', async ({ browser }) => { }); }); +test('Settings - Admin - Parameter', async ({ browser }) => { + const page = await doCachedLogin(browser, { + username: 'admin', + password: 'inventree' + }); + await page.getByRole('button', { name: 'admin' }).click(); + await page.getByRole('menuitem', { name: 'Admin Center' }).click(); + + await loadTab(page, 'Parameters', true); + + await page.waitForTimeout(1000); + await page.waitForLoadState('networkidle'); + + // Clean old template data if exists + await page + .getByRole('cell', { name: 'my custom parameter' }) + .waitFor({ timeout: 500 }) + .then(async (cell) => { + await page + .getByRole('cell', { name: 'my custom parameter' }) + .locator('..') + .getByLabel('row-action-menu-') + .click(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'Delete' }).click(); + }) + .catch(() => {}); + + await page.getByRole('button', { name: 'Selection Lists' }).click(); + // Allow time for the table to load + await page.waitForTimeout(1000); + await page.waitForLoadState('networkidle'); + + // Clean old list data if exists + await page + .getByRole('cell', { name: 'some list' }) + .waitFor({ timeout: 500 }) + .then(async (cell) => { + await page + .getByRole('cell', { name: 'some list' }) + .locator('..') + .getByLabel('row-action-menu-') + .click(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'Delete' }).click(); + }) + .catch(() => {}); + + // Add selection list + await page.getByLabel('action-button-add-selection-').waitFor(); + await page.getByLabel('action-button-add-selection-').click(); + await page.getByLabel('text-field-name').fill('some list'); + await page.getByLabel('text-field-description').fill('Listdescription'); + await page.getByRole('button', { name: 'Submit' }).click(); + await page.getByRole('cell', { name: 'some list' }).waitFor(); + + await page.getByLabel('action-button-add-parameter').waitFor(); + await page.getByLabel('action-button-add-parameter').click(); + await page.getByLabel('text-field-name').fill('my custom parameter'); + await page.getByLabel('text-field-description').fill('description'); + await page + .locator('div') + .filter({ hasText: /^Search\.\.\.$/ }) + .nth(2) + .click(); + await page + .getByRole('option', { name: 'some list' }) + .locator('div') + .first() + .click(); + await page.getByRole('button', { name: 'Submit' }).click(); + await page.getByRole('cell', { name: 'my custom parameter' }).click(); + + // Fill parameter + await navigate(page, 'part/104/parameters/'); + await page.getByLabel('Parameters').getByText('Parameters').waitFor(); + await page.waitForLoadState('networkidle'); + await page + .getByRole('button', { name: 'action-menu-add-parameters' }) + .click(); + + await page + .getByRole('menuitem', { + name: 'action-menu-add-parameters-create-parameter' + }) + .click(); + + await page.waitForTimeout(500); + + await page.getByText('Add Parameter').waitFor(); + await page + .getByText('Template *Parameter') + .locator('div') + .filter({ hasText: /^Search\.\.\.$/ }) + .first() + .click(); + await page + .getByText('Template *Parameter') + .locator('div') + .filter({ hasText: /^Search\.\.\.$/ }) + .locator('input') + .fill('my custom parameter'); + await page.getByRole('option', { name: 'my custom parameter' }).click(); + await page.getByLabel('choice-field-data').fill('2'); + await page.getByRole('button', { name: 'Submit' }).click(); + + await page.waitForTimeout(2500); +}); + test('Settings - Admin - Unauthorized', async ({ browser }) => { // Try to access "admin" page with a non-staff user const page = await doCachedLogin(browser, { diff --git a/src/frontend/tests/settings/selectionList.spec.ts b/src/frontend/tests/settings/selectionList.spec.ts deleted file mode 100644 index 21507a9d9b..0000000000 --- a/src/frontend/tests/settings/selectionList.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { test } from '../baseFixtures'; -import { navigate } from '../helpers'; -import { doCachedLogin } from '../login'; - -test('PUI - Admin - Parameter', async ({ browser }) => { - const page = await doCachedLogin(browser, { - username: 'admin', - password: 'inventree' - }); - await page.getByRole('button', { name: 'admin' }).click(); - await page.getByRole('menuitem', { name: 'Admin Center' }).click(); - await page.getByRole('tab', { name: 'Part Parameters' }).click(); - - await page.getByRole('button', { name: 'Selection Lists' }).click(); - await page.waitForLoadState('networkidle'); - - // clean old data if exists - await page - .getByRole('cell', { name: 'some list' }) - .waitFor({ timeout: 200 }) - .then(async (cell) => { - await page - .getByRole('cell', { name: 'some list' }) - .locator('..') - .getByLabel('row-action-menu-') - .click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('button', { name: 'Delete' }).click(); - }) - .catch(() => {}); - - // clean old data if exists - await page.getByRole('button', { name: 'Part Parameter Template' }).click(); - await page.waitForLoadState('networkidle'); - await page - .getByRole('cell', { name: 'my custom parameter' }) - .waitFor({ timeout: 200 }) - .then(async (cell) => { - await page - .getByRole('cell', { name: 'my custom parameter' }) - .locator('..') - .getByLabel('row-action-menu-') - .click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('button', { name: 'Delete' }).click(); - }) - .catch(() => {}); - - // Add selection list - await page.getByRole('button', { name: 'Selection Lists' }).click(); - await page.waitForLoadState('networkidle'); - await page.getByLabel('action-button-add-selection-').waitFor(); - await page.getByLabel('action-button-add-selection-').click(); - await page.getByLabel('text-field-name').fill('some list'); - await page.getByLabel('text-field-description').fill('Listdescription'); - await page.getByRole('button', { name: 'Submit' }).click(); - await page.getByRole('cell', { name: 'some list' }).waitFor(); - await page.waitForTimeout(200); - - // Add parameter - await page.waitForLoadState('networkidle'); - await page.getByRole('button', { name: 'Part Parameter Template' }).click(); - await page.getByLabel('action-button-add-parameter').waitFor(); - await page.getByLabel('action-button-add-parameter').click(); - await page.getByLabel('text-field-name').fill('my custom parameter'); - await page.getByLabel('text-field-description').fill('description'); - await page - .locator('div') - .filter({ hasText: /^Search\.\.\.$/ }) - .nth(2) - .click(); - await page - .getByRole('option', { name: 'some list' }) - .locator('div') - .first() - .click(); - await page.getByRole('button', { name: 'Submit' }).click(); - await page.getByRole('cell', { name: 'my custom parameter' }).click(); - - // Fill parameter - await navigate(page, 'part/104/parameters/'); - await page.getByLabel('Parameters').getByText('Parameters').waitFor(); - await page.waitForLoadState('networkidle'); - await page.getByLabel('action-button-add-parameter').waitFor(); - await page.getByLabel('action-button-add-parameter').click(); - await page.waitForTimeout(200); - await page.getByText('New Part Parameter').waitFor(); - await page - .getByText('Template *Parameter') - .locator('div') - .filter({ hasText: /^Search\.\.\.$/ }) - .first() - .click(); - await page - .getByText('Template *Parameter') - .locator('div') - .filter({ hasText: /^Search\.\.\.$/ }) - .locator('input') - .fill('my custom parameter'); - await page.getByRole('option', { name: 'my custom parameter' }).click(); - await page.getByLabel('choice-field-data').fill('2'); - await page.getByRole('button', { name: 'Submit' }).click(); -});