Compare commits

...

5 Commits

Author SHA1 Message Date
Jason Novinger
8c49019ed9
Merge 1984f52305 into 9c2cd66162 2025-07-09 10:54:11 -04:00
Olexandr88
9c2cd66162 Update README.md
Some checks failed
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
2025-07-09 10:53:40 -04:00
github-actions
f61a2964c8 Update source translation strings 2025-07-09 05:04:52 +00:00
Jason Novinger
1984f52305 Fixes up ModuleTypeTestCase to include bulk import testing
Also includes an additional regression assertion.
2025-07-02 08:46:41 -04:00
Jason Novinger
255e3881dd Fixes #19800: ModuleType import supports associating ModuleTypeProfile 2025-07-02 08:41:51 -04:00
4 changed files with 72 additions and 20 deletions

View File

@ -6,7 +6,7 @@
<a href="https://github.com/netbox-community/netbox/graphs/contributors"><img src="https://img.shields.io/github/contributors/netbox-community/netbox?color=blue" alt="Contributors" /></a> <a href="https://github.com/netbox-community/netbox/graphs/contributors"><img src="https://img.shields.io/github/contributors/netbox-community/netbox?color=blue" alt="Contributors" /></a>
<a href="https://github.com/netbox-community/netbox/stargazers"><img src="https://img.shields.io/github/stars/netbox-community/netbox?style=flat" alt="GitHub stars" /></a> <a href="https://github.com/netbox-community/netbox/stargazers"><img src="https://img.shields.io/github/stars/netbox-community/netbox?style=flat" alt="GitHub stars" /></a>
<a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-15-blue" alt="Languages supported" /></a> <a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-15-blue" alt="Languages supported" /></a>
<a href="https://github.com/netbox-community/netbox/actions/workflows/ci.yml"><img src="https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=main" alt="CI status" /></a> <a href="https://github.com/netbox-community/netbox/actions/workflows/ci.yml"><img src="https://github.com/netbox-community/netbox/actions/workflows/ci.yml/badge.svg" alt="CI status" /></a>
<p> <p>
<strong><a href="https://netboxlabs.com/community/">NetBox Community</a></strong> | <strong><a href="https://netboxlabs.com/community/">NetBox Community</a></strong> |
<strong><a href="https://netboxlabs.com/netbox-cloud/">NetBox Cloud</a></strong> | <strong><a href="https://netboxlabs.com/netbox-cloud/">NetBox Cloud</a></strong> |

View File

@ -471,7 +471,7 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
model = ModuleType model = ModuleType
fields = [ fields = [
'manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', 'manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments',
'tags', 'tags', 'profile',
] ]

View File

@ -3,17 +3,18 @@ from decimal import Decimal
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
import yaml import yaml
from django.test import override_settings from django.test import override_settings, tag
from django.urls import reverse from django.urls import reverse
from netaddr import EUI from netaddr import EUI
from core.models import ObjectType
from dcim.choices import * from dcim.choices import *
from dcim.constants import * from dcim.constants import *
from dcim.models import * from dcim.models import *
from ipam.models import ASN, RIR, VLAN, VRF from ipam.models import ASN, RIR, VLAN, VRF
from netbox.choices import CSVDelimiterChoices, ImportFormatChoices, WeightUnitChoices from netbox.choices import CSVDelimiterChoices, ImportFormatChoices, WeightUnitChoices
from tenancy.models import Tenant from tenancy.models import Tenant
from users.models import User from users.models import ObjectPermission, User
from utilities.testing import ViewTestCases, create_tags, create_test_device, post_data from utilities.testing import ViewTestCases, create_tags, create_test_device, post_data
from wireless.models import WirelessLAN from wireless.models import WirelessLAN
@ -1000,18 +1001,7 @@ inventory-items:
self.assertEqual(response.get('Content-Type'), 'text/csv; charset=utf-8') self.assertEqual(response.get('Content-Type'), 'text/csv; charset=utf-8')
# TODO: Change base class to PrimaryObjectViewTestCase class ModuleTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
# Blocked by absence of bulk import view for ModuleTypes
class ModuleTypeTestCase(
ViewTestCases.GetObjectViewTestCase,
ViewTestCases.GetObjectChangelogViewTestCase,
ViewTestCases.CreateObjectViewTestCase,
ViewTestCases.EditObjectViewTestCase,
ViewTestCases.DeleteObjectViewTestCase,
ViewTestCases.ListObjectsViewTestCase,
ViewTestCases.BulkEditObjectsViewTestCase,
ViewTestCases.BulkDeleteObjectsViewTestCase
):
model = ModuleType model = ModuleType
@classmethod @classmethod
@ -1023,7 +1013,7 @@ class ModuleTypeTestCase(
) )
Manufacturer.objects.bulk_create(manufacturers) Manufacturer.objects.bulk_create(manufacturers)
ModuleType.objects.bulk_create([ module_types = ModuleType.objects.bulk_create([
ModuleType(model='Module Type 1', manufacturer=manufacturers[0]), ModuleType(model='Module Type 1', manufacturer=manufacturers[0]),
ModuleType(model='Module Type 2', manufacturer=manufacturers[0]), ModuleType(model='Module Type 2', manufacturer=manufacturers[0]),
ModuleType(model='Module Type 3', manufacturer=manufacturers[0]), ModuleType(model='Module Type 3', manufacturer=manufacturers[0]),
@ -1031,6 +1021,8 @@ class ModuleTypeTestCase(
tags = create_tags('Alpha', 'Bravo', 'Charlie') tags = create_tags('Alpha', 'Bravo', 'Charlie')
fan_module_type_profile = ModuleTypeProfile.objects.get(name='Fan')
cls.form_data = { cls.form_data = {
'manufacturer': manufacturers[1].pk, 'manufacturer': manufacturers[1].pk,
'model': 'Device Type X', 'model': 'Device Type X',
@ -1044,6 +1036,62 @@ class ModuleTypeTestCase(
'part_number': '456DEF', 'part_number': '456DEF',
} }
cls.csv_data = (
"manufacturer,model,part_number,comments,profile",
f"Manufacturer 1,fan0,generic-fan,,{fan_module_type_profile.name}"
)
cls.csv_update_data = (
"id,model",
f"{module_types[0].id},test model",
)
def _set_module_type_bulk_import_permissions(self, **permission_definition):
obj_perm = ObjectPermission(**permission_definition)
obj_perm.save()
obj_perm.users.add(self.user)
additional_permissions = [
ConsolePortTemplate, ConsoleServerPortTemplate, PowerPortTemplate, PowerOutletTemplate,
InterfaceTemplate, FrontPortTemplate, RearPortTemplate, ModuleBayTemplate,
]
for model in additional_permissions:
obj_perm.object_types.add(ObjectType.objects.get_for_model(model))
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
def test_bulk_update_objects_with_permission(self):
self._set_module_type_bulk_import_permissions(
name='Expanded ModuleType bulk import add permissions', actions=['add']
)
# run base test
super().test_bulk_update_objects_with_permission()
@tag('regression')
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[])
def test_bulk_import_objects_with_permission(self):
self._set_module_type_bulk_import_permissions(
name='Expanded ModuleType bulk import add permissions', actions=['add']
)
# run base test
super().test_bulk_import_objects_with_permission()
# extra regression asserts
fan_module_type = ModuleType.objects.get(part_number='generic-fan')
fan_module_type_profile = ModuleTypeProfile.objects.get(name='Fan')
assert fan_module_type.profile == fan_module_type_profile
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], EXEMPT_EXCLUDE_MODELS=[])
def test_bulk_import_objects_with_constrained_permission(self):
self._set_module_type_bulk_import_permissions(
name='Expanded ModuleType bulk import add permissions',
constraints={'pk': 0}, # Dummy permission to deny all
actions=['add']
)
super().test_bulk_import_objects_with_constrained_permission()
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*']) @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
def test_moduletype_consoleports(self): def test_moduletype_consoleports(self):
moduletype = ModuleType.objects.first() moduletype = ModuleType.objects.first()

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-03 05:04+0000\n" "POT-Creation-Date: 2025-07-09 05:04+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -13021,7 +13021,7 @@ msgid "Cable Trace for %(object_type)s %(object)s"
msgstr "" msgstr ""
#: netbox/templates/dcim/cable_trace.html:24 #: netbox/templates/dcim/cable_trace.html:24
#: netbox/templates/dcim/inc/rack_elevation.html:7 #: netbox/templates/dcim/inc/rack_elevation.html:18
msgid "Download SVG" msgid "Download SVG"
msgstr "" msgstr ""
@ -13424,10 +13424,14 @@ msgstr ""
msgid "Descending Units" msgid "Descending Units"
msgstr "" msgstr ""
#: netbox/templates/dcim/inc/rack_elevation.html:3 #: netbox/templates/dcim/inc/rack_elevation.html:7
msgid "Rack elevation" msgid "Rack elevation"
msgstr "" msgstr ""
#: netbox/templates/dcim/inc/rack_elevation.html:11
msgid "Loading..."
msgstr ""
#: netbox/templates/dcim/interface.html:17 #: netbox/templates/dcim/interface.html:17
msgid "Add Child Interface" msgid "Add Child Interface"
msgstr "" msgstr ""