# -*- coding: utf-8 -*-
# Copyright (C) 2011, 2012  Michał Masłowski  <mtjm@mtjm.eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""Tests for `hclient.devices`."""


import unittest


class FindSubclassesTestCase(unittest.TestCase):

	"""Tests for functions searching subclasses of `hclient.devices.Device`."""

	def test_class_none(self):
		"""Test getting device objects for an unknown PCI device class"""
		from hclient import devices
		self.assertTrue(devices.get_device_type_for_class(12345) is None)

	def test_class_known(self):
		"""Test getting device objects for an known USB device class"""
		from hclient import devices, devicetypes
		self.assertEquals(devices.get_device_type_for_class(0xffffff),
						  devicetypes.Unknown)

	def test_type_none(self):
		"""Test getting device objects for an unknown device type"""
		from hclient import devices
		self.assertTrue(devices.get_device_type_for_type("kind") is None)

	def test_type_known(self):
		"""Test getting device objects for an known device type"""
		from hclient import devices, devicetypes
		self.assertEquals(devices.get_device_type_for_type("soundcard"),
						  devicetypes.SoundCard)

	def test_types(self):
		"""Test that all type names are listed"""
		from hclient import devices
		self.assertEquals(frozenset(('acquisition-card', 'soundcard', 'bluetooth', 'sd-card-reader', 'printer', 'wifi', 'fingerprint-reader', '3G-card', 'ethernet-card', 'scanner', 'webcam', 'unknown', 'videocard')),
						  frozenset(devices.get_types()))

	def test_types_unique(self):
		"""Test that no type name is listed twice"""
		from hclient import devices
		type_list = devices.get_types()
		self.assertEquals(len(frozenset(type_list)), len(type_list))

	def test_get_type_for_class_known(self):
		"""Test getting type name for a known PCI class"""
		from hclient import devices
		self.assertEquals("printer", devices.get_type_for_class(0x070103))

	def test_get_type_for_class_unknown(self):
		"""Test getting type name for an unknown PCI class"""
		from hclient import devices
		self.assertTrue(devices.get_type_for_class(1234567) is None)

	def test_get_class_for_type_known(self):
		"""Test getting PCI class for a known type"""
		from hclient import devices
		self.assertEquals(0x0400,
						  devices.get_class_for_type("acquisition-card"))

	def test_get_class_for_type_unknown(self):
		"""Test getting PCI class for an unknown type"""
		from hclient import devices
		self.assertTrue(devices.get_class_for_type("debugger") is None)


def _make_devices():
	"""Return a devices dictionary using example ``lspci`` output."""
	from hclient.machine import createDevices, parse_lspci
	from tests_hclient.machine import _LSPCI_OUTPUT

	return createDevices(parse_lspci(_LSPCI_OUTPUT), {})


class DevicesTestCase(unittest.TestCase):

	"""Tests for methods of `Device` and subclasses."""

	def test_othernames_has(self):
		"""Test that other names can be made"""
		device = _make_devices()["p_10de:054c"][0]
		self.assertEquals("1043:82b3	ASUSTeK Computer Inc.	Device",
						  device.createOtherNamesEntry())

	def test_othernames_hasnt(self):
		"""Tests that other names are not made if empty"""
		device = _make_devices()["p_10de:01df"][0]
		self.assertEquals("",
						  device.createOtherNamesEntry())


class DataTestCase(unittest.TestCase):

	"""Tests for serialization of `Device`."""

	def prepare_device(self):
		"""Return a device for tests."""
		from hclient.devices import Device
		from hclient.devicetypes import Wifi
		# From http://www.h-node.org/wifi/view/en/8/Atheros-Communications-Inc--AR922X-Wireless-Network-Adapter/8/1
		device = Device(Wifi)
		device.setModel("Atheros Communications Inc. AR922X Wireless Network Adapter")
		device.setYear(2008)
		device.setDistributions(("trisquel_4_0",))
		device.addDistribution("trisquel_4_5")
		device.addOtherName("TP-LINK TL-WN851N")
		device.addOtherName("TP-LINK TL-WN861N")
		device.addOtherName("D-Link DWA-552 Xtreme N Desktop Adapter")
		device.kernel = "2.6.32-24-generic"
		device.how_it_works = device.type.how_it_works_post.index("yes")
		device.setBus("PCI")
		device.setVendor("Atheros")
		device.setVendorId(0x168c)
		device.setProductId(0x0029)
		device.setSubsystemVendor("Atheros Communications Inc.")
		device.setSubVendorId(0x168c)
		device.setSubsystemName("Device")
		device.setSubProductId(0x2091)
		device.setDriver("ath9k")
		device.setDescription("""[p]This is an Atheros AR9223 chipset, which uses the officially supported free ath9k Linux driver.[/p]

[p]The [a]http://www.tp-link.com/en/products/prodetail.aspx?id=389|TP-LINK TL-WN851N[/a] is a PCI card.[/p]

[p]The [a]http://www.tp-link.com/en/products/prodetail.aspx?id=717|TP-LINK TL-WN861N[/a] is a Mini-PCI card.[/p]

[p]The [a]http://www.dlink.com/products/?pid=531|D-Link DWA-552 Xtreme N Desktop Adapter[/a] is a PCI card.[/p]

[p]This chipset has been tested with IEEE 802.11g and 802.11n networks, unsecured and secured (WPA2-PSK).[/p]

[code]$ lspci -nnkd 168c:0029
06:02.0 Network controller [0280]: Atheros Communications Inc. AR922X Wireless Network Adapter [168c:0029] (rev 01)
        Subsystem: Atheros Communications Inc. Device [168c:2091]
        Kernel driver in use: ath9k
        Kernel modules: ath9k[/code]""")
		return device, {
			'kernel': '2.6.32-24-generic',
			'wifi_works': 'yes',
			'comm_year': '2008',
			'driver': 'ath9k',
			'other_names': '168c:2091\tAtheros Communications Inc.\tDevice\r\nTP-LINK TL-WN861N\r\nTP-LINK TL-WN851N\r\nD-Link DWA-552 Xtreme N Desktop Adapter',
			'pci_id': '168c:0029',
			'interface': 'not-specified',
			'model': 'Atheros Communications Inc. AR922X Wireless Network Adapter',
			'distribution': 'trisquel_4_0 , trisquel_4_5',
			'description': '[p]This is an Atheros AR9223 chipset, which uses the officially supported free ath9k Linux driver.[/p]\r\n\r\n[p]The [a]http://www.tp-link.com/en/products/prodetail.aspx?id=389|TP-LINK TL-WN851N[/a] is a PCI card.[/p]\r\n\r\n[p]The [a]http://www.tp-link.com/en/products/prodetail.aspx?id=717|TP-LINK TL-WN861N[/a] is a Mini-PCI card.[/p]\r\n\r\n[p]The [a]http://www.dlink.com/products/?pid=531|D-Link DWA-552 Xtreme N Desktop Adapter[/a] is a PCI card.[/p]\r\n\r\n[p]This chipset has been tested with IEEE 802.11g and 802.11n networks, unsecured and secured (WPA2-PSK).[/p]\r\n\r\n[code]$ lspci -nnkd 168c:0029\r\n06:02.0 Network controller [0280]: Atheros Communications Inc. AR922X Wireless Network Adapter [168c:0029] (rev 01)\r\n        Subsystem: Atheros Communications Inc. Device [168c:2091]\r\n        Kernel driver in use: ath9k\r\n        Kernel modules: ath9k[/code]'}

	def test_wifi_serialization(self):
		"""Test serialization of a wifi card"""
		device, data = self.prepare_device()
		self.assertEquals(device.data, data)

	def test_no_year(self):
		"""Test serialization of a device without a commercialization year"""
		device, data = self.prepare_device()
		device.setYear(None)
		data["comm_year"] = "not-specified"
		self.assertEquals(device.data, data)

	def test_no_empty_othernames(self):
		"""Test that empty other names are ignored"""
		device, data = self.prepare_device()
		device.addOtherName(" \t\f")
		self.assertEquals(device.data, data)

	def test_distro(self):
		"""Test creative lists of distros"""
		device, data = self.prepare_device()
		device.setDistributions(("", "trisquel_4_0", "gnewsense_2_3",
								 "parabola", "trisquel_4_0"))
		self.assertEquals(device.data["distribution"],
						  "gnewsense_2_3 , parabola , trisquel_4_0")

	def test_unknown_device(self):
		"""Test that unknown devices don't work"""
		from hclient.devices import Device
		from hclient.devicetypes import Unknown
		device = Device(Unknown)
		self.assertEquals(set(device.data.keys()),
						  set(('kernel', 'comm_year','driver', 'other_names',
							   'pci_id', 'interface', 'model', 'distribution',
							   'description')))

	def test_printer(self):
		"""Test serializing printer-specific fields"""
		from hclient.devices import Device
		from hclient.devicetypes import Printer
		device = Device(Printer)
		device.tracks_users = device.type.tracks_users_post.index("yes")
		device.how_it_works = device.type.how_it_works_post.index("C-None")
		device.subtype = device.type.subtypes_post.index("other")
		self.assertEquals(device.data["it_tracks_users"], "yes")
		self.assertEquals(device.data["compatibility"], "C-None")
		self.assertEquals(device.data["subtype"], "other")

# Local Variables:
# indent-tabs-mode: t
# python-guess-indent: nil
# python-indent: 4
# tab-width: 4
# End:
