From bebd6a60fbf456453cd45a228b0aaedf42f5e5ad Mon Sep 17 00:00:00 2001
From: Kelly Brazil <kellyjonbrazil@gmail.com>
Date: Sun, 18 May 2025 19:24:54 -0700
Subject: [PATCH] add team-port.config and fix for blank values

---
 CHANGELOG                                     |   3 +
 jc/parsers/nmcli.py                           |  30 ++--
 .../nmcli-team-and-team-port-config.json      |   1 +
 .../nmcli-team-and-team-port-config.out       | 116 +++++++++++++
 .../generic/nmcli-team-config-blank.json      |   1 +
 .../generic/nmcli-team-config-blank.out       |  97 +++++++++++
 tests/fixtures/generic/nmcli-team-config.json |   1 +
 tests/fixtures/generic/nmcli-team-config.out  | 104 +++++++++++
 .../generic/nmcli-team-port-config-blank.json |   1 +
 .../generic/nmcli-team-port-config-blank.out  |  47 +++++
 .../generic/nmcli-team-port-config.json       |   1 +
 .../generic/nmcli-team-port-config.out        |  52 ++++++
 tests/test_jc.py                              |  25 +++
 tests/test_nmcli.py                           | 161 ++++++------------
 14 files changed, 524 insertions(+), 116 deletions(-)
 create mode 100644 tests/fixtures/generic/nmcli-team-and-team-port-config.json
 create mode 100644 tests/fixtures/generic/nmcli-team-and-team-port-config.out
 create mode 100644 tests/fixtures/generic/nmcli-team-config-blank.json
 create mode 100644 tests/fixtures/generic/nmcli-team-config-blank.out
 create mode 100644 tests/fixtures/generic/nmcli-team-config.json
 create mode 100644 tests/fixtures/generic/nmcli-team-config.out
 create mode 100644 tests/fixtures/generic/nmcli-team-port-config-blank.json
 create mode 100644 tests/fixtures/generic/nmcli-team-port-config-blank.out
 create mode 100644 tests/fixtures/generic/nmcli-team-port-config.json
 create mode 100644 tests/fixtures/generic/nmcli-team-port-config.out

diff --git a/CHANGELOG b/CHANGELOG
index b81f641a..330647d6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 jc changelog
 
+20250518 v1.25.6
+- Fix `nmcli` command parser to support blank `team.config` JSON value and `team-port.config` JSON value
+
 20250503 v1.25.5
 - Add `amixer` command parser
 - Enhance `iptables` command parser to add default policy statistics fields
diff --git a/jc/parsers/nmcli.py b/jc/parsers/nmcli.py
index 16c85407..7ad5d862 100644
--- a/jc/parsers/nmcli.py
+++ b/jc/parsers/nmcli.py
@@ -36,7 +36,8 @@ These are documented below.
     [
       {
         "<key>":                  string/integer/float,   # [0]
-        "team_config":            object,
+        "team_config":            object/null,
+        "team_port_config":       object/null,
         "dhcp4_option_x": {
           "name":                 string,
           "value":                string/integer/float,
@@ -151,7 +152,7 @@ from jc.exceptions import ParseError
 
 class info():
     """Provides parser metadata (version, author, etc.)"""
-    version = '1.1'
+    version = '1.2'
     description = '`nmcli` command parser'
     author = 'Kelly Brazil'
     author_email = 'kellyjonbrazil@gmail.com'
@@ -320,23 +321,32 @@ def _connection_show_x_parse(data: str) -> List[Dict]:
 
     for line in filter(None, data.splitlines()):
 
-        # fix for team.config, which is multi-line JSON
-        if line.startswith('team.config:'):
+        # fix for team.config and team-port.config, which are multi-line JSON
+        if line.startswith('team.config:') or line.startswith('team-port.config:'):
+            key, value = line.split(':', maxsplit=1)
+            key_team = _normalize_key(key)
+            value_team = value.strip()
+
+            if value_team == '--':
+                team_config_value = []
+                item[key_team] = None
+                continue
+
             in_team_config = True
-            _, value = line.split(':', maxsplit=1)
-            team_config_value.append(value.strip())
-            item['team_config'] = {}
+            team_config_value.append(value_team)
+            item[key_team] = {}
             continue
 
-        if not line.startswith('team.') and in_team_config:
+        STARTSWITH_TEAM = line.startswith('team.') or line.startswith('team-port.')
+        if not STARTSWITH_TEAM and in_team_config:
             team_config_value.append(line.strip())
             continue
 
         in_team_config = False
 
         if team_config_value:
-            # team.config value should always be JSON
-            item['team_config'] = json.loads(''.join(team_config_value))
+            # team.config and team-port.config values should always be JSON
+            item[key_team] = json.loads(''.join(team_config_value))
             team_config_value = []
 
         key, value = line.split(':', maxsplit=1)
diff --git a/tests/fixtures/generic/nmcli-team-and-team-port-config.json b/tests/fixtures/generic/nmcli-team-and-team-port-config.json
new file mode 100644
index 00000000..2b7b408f
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-and-team-port-config.json
@@ -0,0 +1 @@
+[{"connection_id":"Team connection 1","connection_uuid":"258e02c2-d9f9-44bb-8d27-887e11aa1828","connection_stable_id":null,"connection_type":"team","connection_interface_name":"team0","connection_autoconnect":"yes","connection_autoconnect_priority":0,"connection_autoconnect_retries":-1,"connection_autoconnect_retries_text":"default","connection_multi_connect":0,"connection_multi_connect_text":"default","connection_auth_retries":-1,"connection_timestamp":0,"connection_read_only":"no","connection_permissions":null,"connection_zone":null,"connection_master":null,"connection_slave_type":null,"connection_autoconnect_slaves":-1,"connection_autoconnect_slaves_text":"default","connection_secondaries":null,"connection_gateway_ping_timeout":0,"connection_metered":"unknown","connection_lldp":"default","connection_mdns":-1,"connection_mdns_text":"default","connection_llmnr":-1,"connection_llmnr_text":"default","connection_dns_over_tls":-1,"connection_dns_over_tls_text":"default","connection_wait_device_timeout":-1,"ipv4_method":"auto","ipv4_dns":null,"ipv4_dns_search":null,"ipv4_dns_options":null,"ipv4_dns_priority":0,"ipv4_addresses":null,"ipv4_gateway":null,"ipv4_routes":null,"ipv4_route_metric":-1,"ipv4_route_table":0,"ipv4_route_table_text":"unspec","ipv4_routing_rules":null,"ipv4_ignore_auto_routes":"no","ipv4_ignore_auto_dns":"no","ipv4_dhcp_client_id":null,"ipv4_dhcp_iaid":null,"ipv4_dhcp_timeout":0,"ipv4_dhcp_timeout_text":"default","ipv4_dhcp_send_hostname":"yes","ipv4_dhcp_hostname":null,"ipv4_dhcp_fqdn":null,"ipv4_dhcp_hostname_flags":"0x0","ipv4_dhcp_hostname_flags_text":"none","ipv4_never_default":"no","ipv4_may_fail":"yes","ipv4_required_timeout":-1,"ipv4_required_timeout_text":"default","ipv4_dad_timeout":-1,"ipv4_dad_timeout_text":"default","ipv4_dhcp_vendor_class_identifier":null,"ipv4_dhcp_reject_servers":null,"ipv6_method":"auto","ipv6_dns":null,"ipv6_dns_search":null,"ipv6_dns_options":null,"ipv6_dns_priority":0,"ipv6_addresses":null,"ipv6_gateway":null,"ipv6_routes":null,"ipv6_route_metric":-1,"ipv6_route_table":0,"ipv6_route_table_text":"unspec","ipv6_routing_rules":null,"ipv6_ignore_auto_routes":"no","ipv6_ignore_auto_dns":"no","ipv6_never_default":"no","ipv6_may_fail":"yes","ipv6_required_timeout":-1,"ipv6_required_timeout_text":"default","ipv6_ip6_privacy":-1,"ipv6_ip6_privacy_text":"unknown","ipv6_addr_gen_mode":"stable-privacy","ipv6_ra_timeout":0,"ipv6_ra_timeout_text":"default","ipv6_dhcp_duid":null,"ipv6_dhcp_iaid":null,"ipv6_dhcp_timeout":0,"ipv6_dhcp_timeout_text":"default","ipv6_dhcp_send_hostname":"yes","ipv6_dhcp_hostname":null,"ipv6_dhcp_hostname_flags":"0x0","ipv6_dhcp_hostname_flags_text":"none","ipv6_token":null,"team_config":{"runner":{"name":"roundrobin"},"link_watch":{"name":"ethtool"}},"team_notify_peers_count":-1,"team_notify_peers_count_text":"unset","team_notify_peers_interval":-1,"team_notify_peers_interval_text":"unset","team_mcast_rejoin_count":-1,"team_mcast_rejoin_count_text":"unset","team_mcast_rejoin_interval":-1,"team_mcast_rejoin_interval_text":"unset","team_runner":"roundrobin","team_runner_hwaddr_policy":null,"team_runner_tx_hash":null,"team_runner_tx_balancer":null,"team_runner_tx_balancer_interval":-1,"team_runner_tx_balancer_interval_text":"unset","team_runner_active":"yes","team_runner_fast_rate":"no","team_runner_sys_prio":-1,"team_runner_sys_prio_text":"unset","team_runner_min_ports":-1,"team_runner_min_ports_text":"unset","team_runner_agg_select_policy":null,"team_link_watchers":"name=ethtool","team_port_config":{"queue_id":0,"prio":0,"lacp_prio":0,"lacp_key":0},"team_port_queue_id":0,"team_port_queue_id_text":"default","team_port_prio":0,"team_port_prio_text":"unset","team_port_sticky":"no","team_port_lacp_prio":0,"team_port_lacp_key":0,"team_port_lacp_key_text":"default","team_port_link_watchers":null,"proxy_method":"none","proxy_browser_only":"no","proxy_pac_url":null,"proxy_pac_script":null}]
diff --git a/tests/fixtures/generic/nmcli-team-and-team-port-config.out b/tests/fixtures/generic/nmcli-team-and-team-port-config.out
new file mode 100644
index 00000000..f41a80e4
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-and-team-port-config.out
@@ -0,0 +1,116 @@
+connection.id:                          Team connection 1
+connection.uuid:                        258e02c2-d9f9-44bb-8d27-887e11aa1828
+connection.stable-id:                   --
+connection.type:                        team
+connection.interface-name:              team0
+connection.autoconnect:                 yes
+connection.autoconnect-priority:        0
+connection.autoconnect-retries:         -1 (default)
+connection.multi-connect:               0 (default)
+connection.auth-retries:                -1
+connection.timestamp:                   0
+connection.read-only:                   no
+connection.permissions:                 --
+connection.zone:                        --
+connection.master:                      --
+connection.slave-type:                  --
+connection.autoconnect-slaves:          -1 (default)
+connection.secondaries:                 --
+connection.gateway-ping-timeout:        0
+connection.metered:                     unknown
+connection.lldp:                        default
+connection.mdns:                        -1 (default)
+connection.llmnr:                       -1 (default)
+connection.dns-over-tls:                -1 (default)
+connection.wait-device-timeout:         -1
+ipv4.method:                            auto
+ipv4.dns:                               --
+ipv4.dns-search:                        --
+ipv4.dns-options:                       --
+ipv4.dns-priority:                      0
+ipv4.addresses:                         --
+ipv4.gateway:                           --
+ipv4.routes:                            --
+ipv4.route-metric:                      -1
+ipv4.route-table:                       0 (unspec)
+ipv4.routing-rules:                     --
+ipv4.ignore-auto-routes:                no
+ipv4.ignore-auto-dns:                   no
+ipv4.dhcp-client-id:                    --
+ipv4.dhcp-iaid:                         --
+ipv4.dhcp-timeout:                      0 (default)
+ipv4.dhcp-send-hostname:                yes
+ipv4.dhcp-hostname:                     --
+ipv4.dhcp-fqdn:                         --
+ipv4.dhcp-hostname-flags:               0x0 (none)
+ipv4.never-default:                     no
+ipv4.may-fail:                          yes
+ipv4.required-timeout:                  -1 (default)
+ipv4.dad-timeout:                       -1 (default)
+ipv4.dhcp-vendor-class-identifier:      --
+ipv4.dhcp-reject-servers:               --
+ipv6.method:                            auto
+ipv6.dns:                               --
+ipv6.dns-search:                        --
+ipv6.dns-options:                       --
+ipv6.dns-priority:                      0
+ipv6.addresses:                         --
+ipv6.gateway:                           --
+ipv6.routes:                            --
+ipv6.route-metric:                      -1
+ipv6.route-table:                       0 (unspec)
+ipv6.routing-rules:                     --
+ipv6.ignore-auto-routes:                no
+ipv6.ignore-auto-dns:                   no
+ipv6.never-default:                     no
+ipv6.may-fail:                          yes
+ipv6.required-timeout:                  -1 (default)
+ipv6.ip6-privacy:                       -1 (unknown)
+ipv6.addr-gen-mode:                     stable-privacy
+ipv6.ra-timeout:                        0 (default)
+ipv6.dhcp-duid:                         --
+ipv6.dhcp-iaid:                         --
+ipv6.dhcp-timeout:                      0 (default)
+ipv6.dhcp-send-hostname:                yes
+ipv6.dhcp-hostname:                     --
+ipv6.dhcp-hostname-flags:               0x0 (none)
+ipv6.token:                             --
+team.config:                            {
+    "runner": {
+        "name": "roundrobin"
+    },
+    "link_watch": {
+        "name": "ethtool"
+    }
+}
+team.notify-peers-count:                -1 (unset)
+team.notify-peers-interval:             -1 (unset)
+team.mcast-rejoin-count:                -1 (unset)
+team.mcast-rejoin-interval:             -1 (unset)
+team.runner:                            roundrobin
+team.runner-hwaddr-policy:              --
+team.runner-tx-hash:                    --
+team.runner-tx-balancer:                --
+team.runner-tx-balancer-interval:       -1 (unset)
+team.runner-active:                     yes
+team.runner-fast-rate:                  no
+team.runner-sys-prio:                   -1 (unset)
+team.runner-min-ports:                  -1 (unset)
+team.runner-agg-select-policy:          --
+team.link-watchers:                     name=ethtool
+team-port.config:                       {
+    "queue_id": 0,
+    "prio": 0,
+    "lacp_prio": 0,
+    "lacp_key": 0
+}
+team-port.queue-id:                     0 (default)
+team-port.prio:                         0 (unset)
+team-port.sticky:                       no
+team-port.lacp-prio:                    0
+team-port.lacp-key:                     0 (default)
+team-port.link-watchers:                --
+proxy.method:                           none
+proxy.browser-only:                     no
+proxy.pac-url:                          --
+proxy.pac-script:                       --
diff --git a/tests/fixtures/generic/nmcli-team-config-blank.json b/tests/fixtures/generic/nmcli-team-config-blank.json
new file mode 100644
index 00000000..67305caf
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-config-blank.json
@@ -0,0 +1 @@
+[{"connection_id":"Team connection 1","connection_uuid":"258e02c2-d9f9-44bb-8d27-887e11aa1828","connection_stable_id":null,"connection_type":"team","connection_interface_name":"team0","connection_autoconnect":"yes","connection_autoconnect_priority":0,"connection_autoconnect_retries":-1,"connection_autoconnect_retries_text":"default","connection_multi_connect":0,"connection_multi_connect_text":"default","connection_auth_retries":-1,"connection_timestamp":0,"connection_read_only":"no","connection_permissions":null,"connection_zone":null,"connection_master":null,"connection_slave_type":null,"connection_autoconnect_slaves":-1,"connection_autoconnect_slaves_text":"default","connection_secondaries":null,"connection_gateway_ping_timeout":0,"connection_metered":"unknown","connection_lldp":"default","connection_mdns":-1,"connection_mdns_text":"default","connection_llmnr":-1,"connection_llmnr_text":"default","connection_dns_over_tls":-1,"connection_dns_over_tls_text":"default","connection_wait_device_timeout":-1,"ipv4_method":"auto","ipv4_dns":null,"ipv4_dns_search":null,"ipv4_dns_options":null,"ipv4_dns_priority":0,"ipv4_addresses":null,"ipv4_gateway":null,"ipv4_routes":null,"ipv4_route_metric":-1,"ipv4_route_table":0,"ipv4_route_table_text":"unspec","ipv4_routing_rules":null,"ipv4_ignore_auto_routes":"no","ipv4_ignore_auto_dns":"no","ipv4_dhcp_client_id":null,"ipv4_dhcp_iaid":null,"ipv4_dhcp_timeout":0,"ipv4_dhcp_timeout_text":"default","ipv4_dhcp_send_hostname":"yes","ipv4_dhcp_hostname":null,"ipv4_dhcp_fqdn":null,"ipv4_dhcp_hostname_flags":"0x0","ipv4_dhcp_hostname_flags_text":"none","ipv4_never_default":"no","ipv4_may_fail":"yes","ipv4_required_timeout":-1,"ipv4_required_timeout_text":"default","ipv4_dad_timeout":-1,"ipv4_dad_timeout_text":"default","ipv4_dhcp_vendor_class_identifier":null,"ipv4_dhcp_reject_servers":null,"ipv6_method":"auto","ipv6_dns":null,"ipv6_dns_search":null,"ipv6_dns_options":null,"ipv6_dns_priority":0,"ipv6_addresses":null,"ipv6_gateway":null,"ipv6_routes":null,"ipv6_route_metric":-1,"ipv6_route_table":0,"ipv6_route_table_text":"unspec","ipv6_routing_rules":null,"ipv6_ignore_auto_routes":"no","ipv6_ignore_auto_dns":"no","ipv6_never_default":"no","ipv6_may_fail":"yes","ipv6_required_timeout":-1,"ipv6_required_timeout_text":"default","ipv6_ip6_privacy":-1,"ipv6_ip6_privacy_text":"unknown","ipv6_addr_gen_mode":"stable-privacy","ipv6_ra_timeout":0,"ipv6_ra_timeout_text":"default","ipv6_dhcp_duid":null,"ipv6_dhcp_iaid":null,"ipv6_dhcp_timeout":0,"ipv6_dhcp_timeout_text":"default","ipv6_dhcp_send_hostname":"yes","ipv6_dhcp_hostname":null,"ipv6_dhcp_hostname_flags":"0x0","ipv6_dhcp_hostname_flags_text":"none","ipv6_token":null,"team_config":null,"team_notify_peers_count":-1,"team_notify_peers_count_text":"unset","team_notify_peers_interval":-1,"team_notify_peers_interval_text":"unset","team_mcast_rejoin_count":-1,"team_mcast_rejoin_count_text":"unset","team_mcast_rejoin_interval":-1,"team_mcast_rejoin_interval_text":"unset","team_runner":"roundrobin","team_runner_hwaddr_policy":null,"team_runner_tx_hash":null,"team_runner_tx_balancer":null,"team_runner_tx_balancer_interval":-1,"team_runner_tx_balancer_interval_text":"unset","team_runner_active":"yes","team_runner_fast_rate":"no","team_runner_sys_prio":-1,"team_runner_sys_prio_text":"unset","team_runner_min_ports":-1,"team_runner_min_ports_text":"unset","team_runner_agg_select_policy":null,"team_link_watchers":"name=ethtool","proxy_method":"none","proxy_browser_only":"no","proxy_pac_url":null,"proxy_pac_script":null}]
diff --git a/tests/fixtures/generic/nmcli-team-config-blank.out b/tests/fixtures/generic/nmcli-team-config-blank.out
new file mode 100644
index 00000000..1be2b38e
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-config-blank.out
@@ -0,0 +1,97 @@
+connection.id:                          Team connection 1
+connection.uuid:                        258e02c2-d9f9-44bb-8d27-887e11aa1828
+connection.stable-id:                   --
+connection.type:                        team
+connection.interface-name:              team0
+connection.autoconnect:                 yes
+connection.autoconnect-priority:        0
+connection.autoconnect-retries:         -1 (default)
+connection.multi-connect:               0 (default)
+connection.auth-retries:                -1
+connection.timestamp:                   0
+connection.read-only:                   no
+connection.permissions:                 --
+connection.zone:                        --
+connection.master:                      --
+connection.slave-type:                  --
+connection.autoconnect-slaves:          -1 (default)
+connection.secondaries:                 --
+connection.gateway-ping-timeout:        0
+connection.metered:                     unknown
+connection.lldp:                        default
+connection.mdns:                        -1 (default)
+connection.llmnr:                       -1 (default)
+connection.dns-over-tls:                -1 (default)
+connection.wait-device-timeout:         -1
+ipv4.method:                            auto
+ipv4.dns:                               --
+ipv4.dns-search:                        --
+ipv4.dns-options:                       --
+ipv4.dns-priority:                      0
+ipv4.addresses:                         --
+ipv4.gateway:                           --
+ipv4.routes:                            --
+ipv4.route-metric:                      -1
+ipv4.route-table:                       0 (unspec)
+ipv4.routing-rules:                     --
+ipv4.ignore-auto-routes:                no
+ipv4.ignore-auto-dns:                   no
+ipv4.dhcp-client-id:                    --
+ipv4.dhcp-iaid:                         --
+ipv4.dhcp-timeout:                      0 (default)
+ipv4.dhcp-send-hostname:                yes
+ipv4.dhcp-hostname:                     --
+ipv4.dhcp-fqdn:                         --
+ipv4.dhcp-hostname-flags:               0x0 (none)
+ipv4.never-default:                     no
+ipv4.may-fail:                          yes
+ipv4.required-timeout:                  -1 (default)
+ipv4.dad-timeout:                       -1 (default)
+ipv4.dhcp-vendor-class-identifier:      --
+ipv4.dhcp-reject-servers:               --
+ipv6.method:                            auto
+ipv6.dns:                               --
+ipv6.dns-search:                        --
+ipv6.dns-options:                       --
+ipv6.dns-priority:                      0
+ipv6.addresses:                         --
+ipv6.gateway:                           --
+ipv6.routes:                            --
+ipv6.route-metric:                      -1
+ipv6.route-table:                       0 (unspec)
+ipv6.routing-rules:                     --
+ipv6.ignore-auto-routes:                no
+ipv6.ignore-auto-dns:                   no
+ipv6.never-default:                     no
+ipv6.may-fail:                          yes
+ipv6.required-timeout:                  -1 (default)
+ipv6.ip6-privacy:                       -1 (unknown)
+ipv6.addr-gen-mode:                     stable-privacy
+ipv6.ra-timeout:                        0 (default)
+ipv6.dhcp-duid:                         --
+ipv6.dhcp-iaid:                         --
+ipv6.dhcp-timeout:                      0 (default)
+ipv6.dhcp-send-hostname:                yes
+ipv6.dhcp-hostname:                     --
+ipv6.dhcp-hostname-flags:               0x0 (none)
+ipv6.token:                             --
+team.config:                            --
+team.notify-peers-count:                -1 (unset)
+team.notify-peers-interval:             -1 (unset)
+team.mcast-rejoin-count:                -1 (unset)
+team.mcast-rejoin-interval:             -1 (unset)
+team.runner:                            roundrobin
+team.runner-hwaddr-policy:              --
+team.runner-tx-hash:                    --
+team.runner-tx-balancer:                --
+team.runner-tx-balancer-interval:       -1 (unset)
+team.runner-active:                     yes
+team.runner-fast-rate:                  no
+team.runner-sys-prio:                   -1 (unset)
+team.runner-min-ports:                  -1 (unset)
+team.runner-agg-select-policy:          --
+team.link-watchers:                     name=ethtool
+proxy.method:                           none
+proxy.browser-only:                     no
+proxy.pac-url:                          --
+proxy.pac-script:                       --
diff --git a/tests/fixtures/generic/nmcli-team-config.json b/tests/fixtures/generic/nmcli-team-config.json
new file mode 100644
index 00000000..ffa339f8
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-config.json
@@ -0,0 +1 @@
+[{"connection_id":"Team connection 1","connection_uuid":"258e02c2-d9f9-44bb-8d27-887e11aa1828","connection_stable_id":null,"connection_type":"team","connection_interface_name":"team0","connection_autoconnect":"yes","connection_autoconnect_priority":0,"connection_autoconnect_retries":-1,"connection_autoconnect_retries_text":"default","connection_multi_connect":0,"connection_multi_connect_text":"default","connection_auth_retries":-1,"connection_timestamp":0,"connection_read_only":"no","connection_permissions":null,"connection_zone":null,"connection_master":null,"connection_slave_type":null,"connection_autoconnect_slaves":-1,"connection_autoconnect_slaves_text":"default","connection_secondaries":null,"connection_gateway_ping_timeout":0,"connection_metered":"unknown","connection_lldp":"default","connection_mdns":-1,"connection_mdns_text":"default","connection_llmnr":-1,"connection_llmnr_text":"default","connection_dns_over_tls":-1,"connection_dns_over_tls_text":"default","connection_wait_device_timeout":-1,"ipv4_method":"auto","ipv4_dns":null,"ipv4_dns_search":null,"ipv4_dns_options":null,"ipv4_dns_priority":0,"ipv4_addresses":null,"ipv4_gateway":null,"ipv4_routes":null,"ipv4_route_metric":-1,"ipv4_route_table":0,"ipv4_route_table_text":"unspec","ipv4_routing_rules":null,"ipv4_ignore_auto_routes":"no","ipv4_ignore_auto_dns":"no","ipv4_dhcp_client_id":null,"ipv4_dhcp_iaid":null,"ipv4_dhcp_timeout":0,"ipv4_dhcp_timeout_text":"default","ipv4_dhcp_send_hostname":"yes","ipv4_dhcp_hostname":null,"ipv4_dhcp_fqdn":null,"ipv4_dhcp_hostname_flags":"0x0","ipv4_dhcp_hostname_flags_text":"none","ipv4_never_default":"no","ipv4_may_fail":"yes","ipv4_required_timeout":-1,"ipv4_required_timeout_text":"default","ipv4_dad_timeout":-1,"ipv4_dad_timeout_text":"default","ipv4_dhcp_vendor_class_identifier":null,"ipv4_dhcp_reject_servers":null,"ipv6_method":"auto","ipv6_dns":null,"ipv6_dns_search":null,"ipv6_dns_options":null,"ipv6_dns_priority":0,"ipv6_addresses":null,"ipv6_gateway":null,"ipv6_routes":null,"ipv6_route_metric":-1,"ipv6_route_table":0,"ipv6_route_table_text":"unspec","ipv6_routing_rules":null,"ipv6_ignore_auto_routes":"no","ipv6_ignore_auto_dns":"no","ipv6_never_default":"no","ipv6_may_fail":"yes","ipv6_required_timeout":-1,"ipv6_required_timeout_text":"default","ipv6_ip6_privacy":-1,"ipv6_ip6_privacy_text":"unknown","ipv6_addr_gen_mode":"stable-privacy","ipv6_ra_timeout":0,"ipv6_ra_timeout_text":"default","ipv6_dhcp_duid":null,"ipv6_dhcp_iaid":null,"ipv6_dhcp_timeout":0,"ipv6_dhcp_timeout_text":"default","ipv6_dhcp_send_hostname":"yes","ipv6_dhcp_hostname":null,"ipv6_dhcp_hostname_flags":"0x0","ipv6_dhcp_hostname_flags_text":"none","ipv6_token":null,"team_config":{"runner":{"name":"roundrobin"},"link_watch":{"name":"ethtool"}},"team_notify_peers_count":-1,"team_notify_peers_count_text":"unset","team_notify_peers_interval":-1,"team_notify_peers_interval_text":"unset","team_mcast_rejoin_count":-1,"team_mcast_rejoin_count_text":"unset","team_mcast_rejoin_interval":-1,"team_mcast_rejoin_interval_text":"unset","team_runner":"roundrobin","team_runner_hwaddr_policy":null,"team_runner_tx_hash":null,"team_runner_tx_balancer":null,"team_runner_tx_balancer_interval":-1,"team_runner_tx_balancer_interval_text":"unset","team_runner_active":"yes","team_runner_fast_rate":"no","team_runner_sys_prio":-1,"team_runner_sys_prio_text":"unset","team_runner_min_ports":-1,"team_runner_min_ports_text":"unset","team_runner_agg_select_policy":null,"team_link_watchers":"name=ethtool","proxy_method":"none","proxy_browser_only":"no","proxy_pac_url":null,"proxy_pac_script":null}]
diff --git a/tests/fixtures/generic/nmcli-team-config.out b/tests/fixtures/generic/nmcli-team-config.out
new file mode 100644
index 00000000..cfea2058
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-config.out
@@ -0,0 +1,104 @@
+connection.id:                          Team connection 1
+connection.uuid:                        258e02c2-d9f9-44bb-8d27-887e11aa1828
+connection.stable-id:                   --
+connection.type:                        team
+connection.interface-name:              team0
+connection.autoconnect:                 yes
+connection.autoconnect-priority:        0
+connection.autoconnect-retries:         -1 (default)
+connection.multi-connect:               0 (default)
+connection.auth-retries:                -1
+connection.timestamp:                   0
+connection.read-only:                   no
+connection.permissions:                 --
+connection.zone:                        --
+connection.master:                      --
+connection.slave-type:                  --
+connection.autoconnect-slaves:          -1 (default)
+connection.secondaries:                 --
+connection.gateway-ping-timeout:        0
+connection.metered:                     unknown
+connection.lldp:                        default
+connection.mdns:                        -1 (default)
+connection.llmnr:                       -1 (default)
+connection.dns-over-tls:                -1 (default)
+connection.wait-device-timeout:         -1
+ipv4.method:                            auto
+ipv4.dns:                               --
+ipv4.dns-search:                        --
+ipv4.dns-options:                       --
+ipv4.dns-priority:                      0
+ipv4.addresses:                         --
+ipv4.gateway:                           --
+ipv4.routes:                            --
+ipv4.route-metric:                      -1
+ipv4.route-table:                       0 (unspec)
+ipv4.routing-rules:                     --
+ipv4.ignore-auto-routes:                no
+ipv4.ignore-auto-dns:                   no
+ipv4.dhcp-client-id:                    --
+ipv4.dhcp-iaid:                         --
+ipv4.dhcp-timeout:                      0 (default)
+ipv4.dhcp-send-hostname:                yes
+ipv4.dhcp-hostname:                     --
+ipv4.dhcp-fqdn:                         --
+ipv4.dhcp-hostname-flags:               0x0 (none)
+ipv4.never-default:                     no
+ipv4.may-fail:                          yes
+ipv4.required-timeout:                  -1 (default)
+ipv4.dad-timeout:                       -1 (default)
+ipv4.dhcp-vendor-class-identifier:      --
+ipv4.dhcp-reject-servers:               --
+ipv6.method:                            auto
+ipv6.dns:                               --
+ipv6.dns-search:                        --
+ipv6.dns-options:                       --
+ipv6.dns-priority:                      0
+ipv6.addresses:                         --
+ipv6.gateway:                           --
+ipv6.routes:                            --
+ipv6.route-metric:                      -1
+ipv6.route-table:                       0 (unspec)
+ipv6.routing-rules:                     --
+ipv6.ignore-auto-routes:                no
+ipv6.ignore-auto-dns:                   no
+ipv6.never-default:                     no
+ipv6.may-fail:                          yes
+ipv6.required-timeout:                  -1 (default)
+ipv6.ip6-privacy:                       -1 (unknown)
+ipv6.addr-gen-mode:                     stable-privacy
+ipv6.ra-timeout:                        0 (default)
+ipv6.dhcp-duid:                         --
+ipv6.dhcp-iaid:                         --
+ipv6.dhcp-timeout:                      0 (default)
+ipv6.dhcp-send-hostname:                yes
+ipv6.dhcp-hostname:                     --
+ipv6.dhcp-hostname-flags:               0x0 (none)
+ipv6.token:                             --
+team.config:                            {
+    "runner": {
+        "name": "roundrobin"
+    },
+    "link_watch": {
+        "name": "ethtool"
+    }
+}
+team.notify-peers-count:                -1 (unset)
+team.notify-peers-interval:             -1 (unset)
+team.mcast-rejoin-count:                -1 (unset)
+team.mcast-rejoin-interval:             -1 (unset)
+team.runner:                            roundrobin
+team.runner-hwaddr-policy:              --
+team.runner-tx-hash:                    --
+team.runner-tx-balancer:                --
+team.runner-tx-balancer-interval:       -1 (unset)
+team.runner-active:                     yes
+team.runner-fast-rate:                  no
+team.runner-sys-prio:                   -1 (unset)
+team.runner-min-ports:                  -1 (unset)
+team.runner-agg-select-policy:          --
+team.link-watchers:                     name=ethtool
+proxy.method:                           none
+proxy.browser-only:                     no
+proxy.pac-url:                          --
+proxy.pac-script:                       --
diff --git a/tests/fixtures/generic/nmcli-team-port-config-blank.json b/tests/fixtures/generic/nmcli-team-port-config-blank.json
new file mode 100644
index 00000000..46be699d
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-port-config-blank.json
@@ -0,0 +1 @@
+[{"connection_id":"team1","connection_uuid":"a85e0eba-7140-4963-963d-ca9a0f6516ed","connection_stable_id":null,"connection_type":"802-3-ethernet","connection_interface_name":null,"connection_autoconnect":"yes","connection_autoconnect_priority":0,"connection_autoconnect_retries":-1,"connection_autoconnect_retries_text":"default","connection_multi_connect":0,"connection_multi_connect_text":"default","connection_auth_retries":-1,"connection_timestamp":0,"connection_read_only":"no","connection_permissions":null,"connection_zone":null,"connection_master":"d229f048-5c75-40f4-a7ff-61174546c506","connection_slave_type":"team","connection_autoconnect_slaves":-1,"connection_autoconnect_slaves_text":"default","connection_secondaries":null,"connection_gateway_ping_timeout":0,"connection_metered":"unknown","connection_lldp":"default","connection_mdns":-1,"connection_mdns_text":"default","connection_llmnr":-1,"connection_llmnr_text":"default","connection_dns_over_tls":-1,"connection_dns_over_tls_text":"default","connection_wait_device_timeout":-1,"802_3_ethernet_port":null,"802_3_ethernet_speed":0,"802_3_ethernet_duplex":null,"802_3_ethernet_auto_negotiate":"no","802_3_ethernet_mac_address":null,"802_3_ethernet_cloned_mac_address":null,"802_3_ethernet_generate_mac_address_mask":null,"802_3_ethernet_mac_address_blacklist":null,"802_3_ethernet_mtu":"auto","802_3_ethernet_s390_subchannels":null,"802_3_ethernet_s390_nettype":null,"802_3_ethernet_s390_options":null,"802_3_ethernet_wake_on_lan":"default","802_3_ethernet_wake_on_lan_password":null,"802_3_ethernet_accept_all_mac_addresses":-1,"802_3_ethernet_accept_all_mac_addresses_text":"default","team_port_config":null,"team_port_queue_id":0,"team_port_queue_id_text":"default","team_port_prio":0,"team_port_prio_text":"unset","team_port_sticky":"no","team_port_lacp_prio":0,"team_port_lacp_key":0,"team_port_lacp_key_text":"default","team_port_link_watchers":null}]
diff --git a/tests/fixtures/generic/nmcli-team-port-config-blank.out b/tests/fixtures/generic/nmcli-team-port-config-blank.out
new file mode 100644
index 00000000..f14e15ba
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-port-config-blank.out
@@ -0,0 +1,47 @@
+connection.id:                          team1
+connection.uuid:                        a85e0eba-7140-4963-963d-ca9a0f6516ed
+connection.stable-id:                   --
+connection.type:                        802-3-ethernet
+connection.interface-name:              --
+connection.autoconnect:                 yes
+connection.autoconnect-priority:        0
+connection.autoconnect-retries:         -1 (default)
+connection.multi-connect:               0 (default)
+connection.auth-retries:                -1
+connection.timestamp:                   0
+connection.read-only:                   no
+connection.permissions:                 --
+connection.zone:                        --
+connection.master:                      d229f048-5c75-40f4-a7ff-61174546c506
+connection.slave-type:                  team
+connection.autoconnect-slaves:          -1 (default)
+connection.secondaries:                 --
+connection.gateway-ping-timeout:        0
+connection.metered:                     unknown
+connection.lldp:                        default
+connection.mdns:                        -1 (default)
+connection.llmnr:                       -1 (default)
+connection.dns-over-tls:                -1 (default)
+connection.wait-device-timeout:         -1
+802-3-ethernet.port:                    --
+802-3-ethernet.speed:                   0
+802-3-ethernet.duplex:                  --
+802-3-ethernet.auto-negotiate:          no
+802-3-ethernet.mac-address:             --
+802-3-ethernet.cloned-mac-address:      --
+802-3-ethernet.generate-mac-address-mask:--
+802-3-ethernet.mac-address-blacklist:   --
+802-3-ethernet.mtu:                     auto
+802-3-ethernet.s390-subchannels:        --
+802-3-ethernet.s390-nettype:            --
+802-3-ethernet.s390-options:            --
+802-3-ethernet.wake-on-lan:             default
+802-3-ethernet.wake-on-lan-password:    --
+802-3-ethernet.accept-all-mac-addresses:-1 (default)
+team-port.config:                       --
+team-port.queue-id:                     0 (default)
+team-port.prio:                         0 (unset)
+team-port.sticky:                       no
+team-port.lacp-prio:                    0
+team-port.lacp-key:                     0 (default)
+team-port.link-watchers:                --
diff --git a/tests/fixtures/generic/nmcli-team-port-config.json b/tests/fixtures/generic/nmcli-team-port-config.json
new file mode 100644
index 00000000..2a8d2bc5
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-port-config.json
@@ -0,0 +1 @@
+[{"connection_id":"team1","connection_uuid":"a85e0eba-7140-4963-963d-ca9a0f6516ed","connection_stable_id":null,"connection_type":"802-3-ethernet","connection_interface_name":null,"connection_autoconnect":"yes","connection_autoconnect_priority":0,"connection_autoconnect_retries":-1,"connection_autoconnect_retries_text":"default","connection_multi_connect":0,"connection_multi_connect_text":"default","connection_auth_retries":-1,"connection_timestamp":0,"connection_read_only":"no","connection_permissions":null,"connection_zone":null,"connection_master":"d229f048-5c75-40f4-a7ff-61174546c506","connection_slave_type":"team","connection_autoconnect_slaves":-1,"connection_autoconnect_slaves_text":"default","connection_secondaries":null,"connection_gateway_ping_timeout":0,"connection_metered":"unknown","connection_lldp":"default","connection_mdns":-1,"connection_mdns_text":"default","connection_llmnr":-1,"connection_llmnr_text":"default","connection_dns_over_tls":-1,"connection_dns_over_tls_text":"default","connection_wait_device_timeout":-1,"802_3_ethernet_port":null,"802_3_ethernet_speed":0,"802_3_ethernet_duplex":null,"802_3_ethernet_auto_negotiate":"no","802_3_ethernet_mac_address":null,"802_3_ethernet_cloned_mac_address":null,"802_3_ethernet_generate_mac_address_mask":null,"802_3_ethernet_mac_address_blacklist":null,"802_3_ethernet_mtu":"auto","802_3_ethernet_s390_subchannels":null,"802_3_ethernet_s390_nettype":null,"802_3_ethernet_s390_options":null,"802_3_ethernet_wake_on_lan":"default","802_3_ethernet_wake_on_lan_password":null,"802_3_ethernet_accept_all_mac_addresses":-1,"802_3_ethernet_accept_all_mac_addresses_text":"default","team_port_config":{"queue_id":0,"prio":0,"lacp_prio":0,"lacp_key":0},"team_port_queue_id":0,"team_port_queue_id_text":"default","team_port_prio":0,"team_port_prio_text":"unset","team_port_sticky":"no","team_port_lacp_prio":0,"team_port_lacp_key":0,"team_port_lacp_key_text":"default","team_port_link_watchers":null}]
diff --git a/tests/fixtures/generic/nmcli-team-port-config.out b/tests/fixtures/generic/nmcli-team-port-config.out
new file mode 100644
index 00000000..8c0d0d4d
--- /dev/null
+++ b/tests/fixtures/generic/nmcli-team-port-config.out
@@ -0,0 +1,52 @@
+connection.id:                          team1
+connection.uuid:                        a85e0eba-7140-4963-963d-ca9a0f6516ed
+connection.stable-id:                   --
+connection.type:                        802-3-ethernet
+connection.interface-name:              --
+connection.autoconnect:                 yes
+connection.autoconnect-priority:        0
+connection.autoconnect-retries:         -1 (default)
+connection.multi-connect:               0 (default)
+connection.auth-retries:                -1
+connection.timestamp:                   0
+connection.read-only:                   no
+connection.permissions:                 --
+connection.zone:                        --
+connection.master:                      d229f048-5c75-40f4-a7ff-61174546c506
+connection.slave-type:                  team
+connection.autoconnect-slaves:          -1 (default)
+connection.secondaries:                 --
+connection.gateway-ping-timeout:        0
+connection.metered:                     unknown
+connection.lldp:                        default
+connection.mdns:                        -1 (default)
+connection.llmnr:                       -1 (default)
+connection.dns-over-tls:                -1 (default)
+connection.wait-device-timeout:         -1
+802-3-ethernet.port:                    --
+802-3-ethernet.speed:                   0
+802-3-ethernet.duplex:                  --
+802-3-ethernet.auto-negotiate:          no
+802-3-ethernet.mac-address:             --
+802-3-ethernet.cloned-mac-address:      --
+802-3-ethernet.generate-mac-address-mask:--
+802-3-ethernet.mac-address-blacklist:   --
+802-3-ethernet.mtu:                     auto
+802-3-ethernet.s390-subchannels:        --
+802-3-ethernet.s390-nettype:            --
+802-3-ethernet.s390-options:            --
+802-3-ethernet.wake-on-lan:             default
+802-3-ethernet.wake-on-lan-password:    --
+802-3-ethernet.accept-all-mac-addresses:-1 (default)
+team-port.config:                       {
+    "queue_id": 0,
+    "prio": 0,
+    "lacp_prio": 0,
+    "lacp_key": 0
+}
+team-port.queue-id:                     0 (default)
+team-port.prio:                         0 (unset)
+team-port.sticky:                       no
+team-port.lacp-prio:                    0
+team-port.lacp-key:                     0 (default)
+team-port.link-watchers:                --
diff --git a/tests/test_jc.py b/tests/test_jc.py
index 96200b08..0b6975f2 100644
--- a/tests/test_jc.py
+++ b/tests/test_jc.py
@@ -1,7 +1,10 @@
 import unittest
+import os
+import re
 from typing import Generator
 import jc
 
+THIS_DIR = os.path.dirname(os.path.abspath(__file__))
 
 class MyTests(unittest.TestCase):
     def test_jc_parse_csv(self):
@@ -40,5 +43,27 @@ class MyTests(unittest.TestCase):
     def test_jc_slurpable_parser_mod_list_is_list(self):
         self.assertIsInstance(jc.slurpable_parser_mod_list(), list)
 
+    def test_version_info(self):
+        """Test that the lib and pkg version strings match."""
+        with open(os.path.join(THIS_DIR, os.pardir, 'jc/lib.py'), 'r', encoding='utf-8') as f:
+            lib_file = f.read()
+
+        with open(os.path.join(THIS_DIR, os.pardir, 'setup.py'), 'r', encoding='utf-8') as f:
+            pkg_file = f.read()
+
+        lib_pattern = re.compile(r'''__version__ = \'(?P<ver>\d+\.\d+\.\d+)\'''')
+        pkg_pattern = re.compile(r'''    version=\'(?P<ver>\d+\.\d+\.\d+)\'''')
+
+        lib_match = re.search(lib_pattern, lib_file)
+        pkg_match = re.search(pkg_pattern, pkg_file)
+
+        if lib_match:
+            lib_version = lib_match.groupdict()['ver']
+
+        if pkg_match:
+            pkg_version = pkg_match.groupdict()['ver']
+
+        self.assertEqual(lib_version, pkg_version)
+
 if __name__ == '__main__':
     unittest.main()
\ No newline at end of file
diff --git a/tests/test_nmcli.py b/tests/test_nmcli.py
index 5bb90dfa..b975e247 100644
--- a/tests/test_nmcli.py
+++ b/tests/test_nmcli.py
@@ -52,6 +52,21 @@ class MyTests(unittest.TestCase):
     with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/fedora32/nmcli-device-show.out'), 'r', encoding='utf-8') as f:
         fedora32_nmcli_device_show = f.read()
 
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-config.out'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_config = f.read()
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-config-blank.out'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_config_blank = f.read()
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-port-config.out'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_port_config = f.read()
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-port-config-blank.out'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_port_config_blank = f.read()
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-and-team-port-config.out'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_and_team_port_config = f.read()
+
 
     # output
     with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/nmcli-connection-all.json'), 'r', encoding='utf-8') as f:
@@ -93,6 +108,21 @@ class MyTests(unittest.TestCase):
     with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/fedora32/nmcli-device-show.json'), 'r', encoding='utf-8') as f:
         fedora32_nmcli_device_show_json = json.loads(f.read())
 
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-config.json'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_config_json = json.loads(f.read())
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-config-blank.json'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_config_blank_json = json.loads(f.read())
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-port-config.json'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_port_config_json = json.loads(f.read())
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-port-config-blank.json'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_port_config_blank_json = json.loads(f.read())
+
+    with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/nmcli-team-and-team-port-config.json'), 'r', encoding='utf-8') as f:
+        generic_nmcli_team_and_team_port_config_json = json.loads(f.read())
+
 
 
     def test_nmcli_nodata(self):
@@ -189,112 +219,31 @@ class MyTests(unittest.TestCase):
         """
         Test nmcli with team.config JSON value
         """
-        data = '''connection.id:                          Team connection 1
-connection.uuid:                        258e02c2-d9f9-44bb-8d27-887e11aa1828
-connection.stable-id:                   --
-connection.type:                        team
-connection.interface-name:              team0
-connection.autoconnect:                 yes
-connection.autoconnect-priority:        0
-connection.autoconnect-retries:         -1 (default)
-connection.multi-connect:               0 (default)
-connection.auth-retries:                -1
-connection.timestamp:                   0
-connection.read-only:                   no
-connection.permissions:                 --
-connection.zone:                        --
-connection.master:                      --
-connection.slave-type:                  --
-connection.autoconnect-slaves:          -1 (default)
-connection.secondaries:                 --
-connection.gateway-ping-timeout:        0
-connection.metered:                     unknown
-connection.lldp:                        default
-connection.mdns:                        -1 (default)
-connection.llmnr:                       -1 (default)
-connection.dns-over-tls:                -1 (default)
-connection.wait-device-timeout:         -1
-ipv4.method:                            auto
-ipv4.dns:                               --
-ipv4.dns-search:                        --
-ipv4.dns-options:                       --
-ipv4.dns-priority:                      0
-ipv4.addresses:                         --
-ipv4.gateway:                           --
-ipv4.routes:                            --
-ipv4.route-metric:                      -1
-ipv4.route-table:                       0 (unspec)
-ipv4.routing-rules:                     --
-ipv4.ignore-auto-routes:                no
-ipv4.ignore-auto-dns:                   no
-ipv4.dhcp-client-id:                    --
-ipv4.dhcp-iaid:                         --
-ipv4.dhcp-timeout:                      0 (default)
-ipv4.dhcp-send-hostname:                yes
-ipv4.dhcp-hostname:                     --
-ipv4.dhcp-fqdn:                         --
-ipv4.dhcp-hostname-flags:               0x0 (none)
-ipv4.never-default:                     no
-ipv4.may-fail:                          yes
-ipv4.required-timeout:                  -1 (default)
-ipv4.dad-timeout:                       -1 (default)
-ipv4.dhcp-vendor-class-identifier:      --
-ipv4.dhcp-reject-servers:               --
-ipv6.method:                            auto
-ipv6.dns:                               --
-ipv6.dns-search:                        --
-ipv6.dns-options:                       --
-ipv6.dns-priority:                      0
-ipv6.addresses:                         --
-ipv6.gateway:                           --
-ipv6.routes:                            --
-ipv6.route-metric:                      -1
-ipv6.route-table:                       0 (unspec)
-ipv6.routing-rules:                     --
-ipv6.ignore-auto-routes:                no
-ipv6.ignore-auto-dns:                   no
-ipv6.never-default:                     no
-ipv6.may-fail:                          yes
-ipv6.required-timeout:                  -1 (default)
-ipv6.ip6-privacy:                       -1 (unknown)
-ipv6.addr-gen-mode:                     stable-privacy
-ipv6.ra-timeout:                        0 (default)
-ipv6.dhcp-duid:                         --
-ipv6.dhcp-iaid:                         --
-ipv6.dhcp-timeout:                      0 (default)
-ipv6.dhcp-send-hostname:                yes
-ipv6.dhcp-hostname:                     --
-ipv6.dhcp-hostname-flags:               0x0 (none)
-ipv6.token:                             --
-team.config:                            {
-    "runner": {
-        "name": "roundrobin"
-    },
-    "link_watch": {
-        "name": "ethtool"
-    }
-}
-team.notify-peers-count:                -1 (unset)
-team.notify-peers-interval:             -1 (unset)
-team.mcast-rejoin-count:                -1 (unset)
-team.mcast-rejoin-interval:             -1 (unset)
-team.runner:                            roundrobin
-team.runner-hwaddr-policy:              --
-team.runner-tx-hash:                    --
-team.runner-tx-balancer:                --
-team.runner-tx-balancer-interval:       -1 (unset)
-team.runner-active:                     yes
-team.runner-fast-rate:                  no
-team.runner-sys-prio:                   -1 (unset)
-team.runner-min-ports:                  -1 (unset)
-team.runner-agg-select-policy:          --
-team.link-watchers:                     name=ethtool
-proxy.method:                           none
-proxy.browser-only:                     no
-proxy.pac-url:                          --
-proxy.pac-script:                       --'''
-        expected = [{'connection_id': 'Team connection 1', 'connection_uuid': '258e02c2-d9f9-44bb-8d27-887e11aa1828', 'connection_stable_id': None, 'connection_type': 'team', 'connection_interface_name': 'team0', 'connection_autoconnect': 'yes', 'connection_autoconnect_priority': 0, 'connection_autoconnect_retries': -1, 'connection_autoconnect_retries_text': 'default', 'connection_multi_connect': 0, 'connection_multi_connect_text': 'default', 'connection_auth_retries': -1, 'connection_timestamp': 0, 'connection_read_only': 'no', 'connection_permissions': None, 'connection_zone': None, 'connection_master': None, 'connection_slave_type': None, 'connection_autoconnect_slaves': -1, 'connection_autoconnect_slaves_text': 'default', 'connection_secondaries': None, 'connection_gateway_ping_timeout': 0, 'connection_metered': 'unknown', 'connection_lldp': 'default', 'connection_mdns': -1, 'connection_mdns_text': 'default', 'connection_llmnr': -1, 'connection_llmnr_text': 'default', 'connection_dns_over_tls': -1, 'connection_dns_over_tls_text': 'default', 'connection_wait_device_timeout': -1, 'ipv4_method': 'auto', 'ipv4_dns': None, 'ipv4_dns_search': None, 'ipv4_dns_options': None, 'ipv4_dns_priority': 0, 'ipv4_addresses': None, 'ipv4_gateway': None, 'ipv4_routes': None, 'ipv4_route_metric': -1, 'ipv4_route_table': 0, 'ipv4_route_table_text': 'unspec', 'ipv4_routing_rules': None, 'ipv4_ignore_auto_routes': 'no', 'ipv4_ignore_auto_dns': 'no', 'ipv4_dhcp_client_id': None, 'ipv4_dhcp_iaid': None, 'ipv4_dhcp_timeout': 0, 'ipv4_dhcp_timeout_text': 'default', 'ipv4_dhcp_send_hostname': 'yes', 'ipv4_dhcp_hostname': None, 'ipv4_dhcp_fqdn': None, 'ipv4_dhcp_hostname_flags': '0x0', 'ipv4_dhcp_hostname_flags_text': 'none', 'ipv4_never_default': 'no', 'ipv4_may_fail': 'yes', 'ipv4_required_timeout': -1, 'ipv4_required_timeout_text': 'default', 'ipv4_dad_timeout': -1, 'ipv4_dad_timeout_text': 'default', 'ipv4_dhcp_vendor_class_identifier': None, 'ipv4_dhcp_reject_servers': None, 'ipv6_method': 'auto', 'ipv6_dns': None, 'ipv6_dns_search': None, 'ipv6_dns_options': None, 'ipv6_dns_priority': 0, 'ipv6_addresses': None, 'ipv6_gateway': None, 'ipv6_routes': None, 'ipv6_route_metric': -1, 'ipv6_route_table': 0, 'ipv6_route_table_text': 'unspec', 'ipv6_routing_rules': None, 'ipv6_ignore_auto_routes': 'no', 'ipv6_ignore_auto_dns': 'no', 'ipv6_never_default': 'no', 'ipv6_may_fail': 'yes', 'ipv6_required_timeout': -1, 'ipv6_required_timeout_text': 'default', 'ipv6_ip6_privacy': -1, 'ipv6_ip6_privacy_text': 'unknown', 'ipv6_addr_gen_mode': 'stable-privacy', 'ipv6_ra_timeout': 0, 'ipv6_ra_timeout_text': 'default', 'ipv6_dhcp_duid': None, 'ipv6_dhcp_iaid': None, 'ipv6_dhcp_timeout': 0, 'ipv6_dhcp_timeout_text': 'default', 'ipv6_dhcp_send_hostname': 'yes', 'ipv6_dhcp_hostname': None, 'ipv6_dhcp_hostname_flags': '0x0', 'ipv6_dhcp_hostname_flags_text': 'none', 'ipv6_token': None, 'team_config': {'runner': {'name': 'roundrobin'}, 'link_watch': {'name': 'ethtool'}}, 'team_notify_peers_count': -1, 'team_notify_peers_count_text': 'unset', 'team_notify_peers_interval': -1, 'team_notify_peers_interval_text': 'unset', 'team_mcast_rejoin_count': -1, 'team_mcast_rejoin_count_text': 'unset', 'team_mcast_rejoin_interval': -1, 'team_mcast_rejoin_interval_text': 'unset', 'team_runner': 'roundrobin', 'team_runner_hwaddr_policy': None, 'team_runner_tx_hash': None, 'team_runner_tx_balancer': None, 'team_runner_tx_balancer_interval': -1, 'team_runner_tx_balancer_interval_text': 'unset', 'team_runner_active': 'yes', 'team_runner_fast_rate': 'no', 'team_runner_sys_prio': -1, 'team_runner_sys_prio_text': 'unset', 'team_runner_min_ports': -1, 'team_runner_min_ports_text': 'unset', 'team_runner_agg_select_policy': None, 'team_link_watchers': 'name=ethtool', 'proxy_method': 'none', 'proxy_browser_only': 'no', 'proxy_pac_url': None, 'proxy_pac_script': None}]
-        self.assertEqual(jc.parsers.nmcli.parse(data, quiet=True), expected)
+        self.assertEqual(jc.parsers.nmcli.parse(self.generic_nmcli_team_config, quiet=True), self.generic_nmcli_team_config_json)
+
+    def test_nmcli_team_config_blank(self):
+        """
+        Test nmcli with blank team.config JSON value
+        """
+        self.assertEqual(jc.parsers.nmcli.parse(self.generic_nmcli_team_config_blank, quiet=True), self.generic_nmcli_team_config_blank_json)
+
+    def test_nmcli_team_port_config(self):
+        """
+        Test nmcli with team-port.config JSON value
+        """
+        self.assertEqual(jc.parsers.nmcli.parse(self.generic_nmcli_team_port_config, quiet=True), self.generic_nmcli_team_port_config_json)
+
+    def test_nmcli_team_port_config_blank(self):
+        """
+        Test nmcli with blank team-port.config JSON value
+        """
+        self.assertEqual(jc.parsers.nmcli.parse(self.generic_nmcli_team_port_config_blank, quiet=True), self.generic_nmcli_team_port_config_blank_json)
+
+    def test_nmcli_team_and_team_port_config_blank(self):
+        """
+        Test nmcli with both team.config and team-port.config JSON value
+        """
+        self.assertEqual(jc.parsers.nmcli.parse(self.generic_nmcli_team_and_team_port_config, quiet=True), self.generic_nmcli_team_and_team_port_config_json)
 
 
 if __name__ == '__main__':