# Path: labshare/consumers.py
# class GPUInfoUpdater(WebsocketConsumer):
#     def connect(self):
#         self.user = self.scope['user']
#         self.device_name = self.scope['url_route']['kwargs']['device_name']
# 
#         device = Device.objects.get(name=self.device_name)
#         if device.can_be_used_by(self.user):
#             async_to_sync(self.channel_layer.group_add)(
#                 self.device_name,
#                 self.channel_name,
#             )
# 
#             publish_device_state(device.serialize(), self.channel_name)
# 
#             self.accept()
#         else:
#             self.close()
# 
#     def disconnect(self, message, **kwargs):
#         async_to_sync(self.channel_layer.group_discard)(
#             self.device_name,
#             self.channel_name,
#         )
# 
#     def update_info(self, event):
#         self.send(text_data=event['message'])
# 
# Path: labshare/models.py
# class Device(models.Model):
#     name = models.CharField(max_length=255)
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
# 
#     class Meta:
#         permissions = (
#             ('use_device', 'User/Group is allowed to use that device'),
#         )
# 
#     def __str__(self):
#         return self.name
# 
#     def can_be_used_by(self, user):
#         content_type = ContentType.objects.get_for_model(self)
#         permission_name = "{app}.use_{model}".format(app=content_type.app_label, model=content_type.model)
#         return user.has_perm(permission_name, self) or user.has_perm(permission_name)
# 
#     def serialize(self):
#         return {
#             'name': self.name,
#         }
# 
# class EmailAddress(models.Model):
#     user = models.ForeignKey(User, related_name="email_addresses", on_delete=models.CASCADE)
#     email = models.EmailField(max_length=255)
# 
#     def __str__(self):
#         return "{}: {}".format(self.user, self.email)
# 
# class GPU(models.Model):
#     uuid = models.CharField(max_length=255)
#     model_name = models.CharField(max_length=255)
#     reserved = models.BooleanField(default=False)
#     device = models.ForeignKey(Device, related_name='gpus', on_delete=models.CASCADE)
# 
#     def serialize(self):
#         return {
#             'uuid': self.uuid,
#             'model_name': self.model_name,
#             'reserved': self.reserved
#         }
# 
# Path: labshare/routing.py

# 
# Path: labshare/templatetags/icon.py
# @register.tag
# def icon(parser, token):
#     split = token.contents.split(' ')
#     if len(split) < 2:
#         return no_icon_error()
#     if len(split) > 2:
#         raise template.TemplateSyntaxError("too many arguments!")
#     icon_name = extract_string(token.contents.split(' ')[1])
# 
#     return IconNode(icon_name)
# 
# Path: labshare/utils.py
# def get_devices():
#     return [(device.name, device.name) for device in Device.objects.all()]
# 
# def publish_device_state(device_data, channel_name=None):
#     channel_layer = channels.layers.get_channel_layer()
#     name = device_data['name']
#     if 'gpus' not in device_data:
#         device_data['gpus'] = []
# 
#     if channel_name is None:
#         send_function = async_to_sync(channel_layer.group_send)
#     else:
#         send_function = async_to_sync(channel_layer.send)
#     send_function(channel_name if channel_name else name, {'type': 'update_info', 'message': json.dumps(device_data)})


import copy
import datetime
import io
import json
import os
import random
import string
import time
import unittest.mock as mock
import uuid
import requests
from datetime import timedelta
from unittest import skipIf
from unittest.mock import Mock
from channels.layers import get_channel_layer
from channels.testing import ChannelsLiveServerTestCase, WebsocketCommunicator
from django import template
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.core import mail
from django.test import TestCase, override_settings, Client
from django.urls import reverse
from django_webtest import WebTest
from guardian.shortcuts import assign_perm
from guardian.utils import get_anonymous_user
from model_bakery import baker
from model_bakery.recipe import Recipe
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from labshare.consumers import GPUInfoUpdater
from labshare.models import Device, EmailAddress, GPU
from labshare.routing import application
from labshare.templatetags.icon import icon
from labshare.utils import get_devices, publish_device_state

        for device in self.devices[:-1]:
            assign_perm('use_device', self.student_group, device)

        self.staff_group = baker.make(Group, name="staff")
        self.staff_user.groups.add(self.staff_group)

        for device in self.devices:
            assign_perm('use_device', self.staff_group, device)

    def test_overview_correct(self):
        response = self.app.get(reverse('index'), user=self.user)
        response_text = response.body.decode('utf-8')
        for device in self.devices[:-1]:
            self.assertIn(device.name, response_text)
        self.assertNotIn(self.devices[-1].name, response_text)

        response = self.app.get(reverse("index"), user=self.staff_user)
        for device in self.devices:
            self.assertIn(device.name, response.body.decode('utf-8'))

        response = self.app.get(reverse("index"), user=get_anonymous_user())
        for device in self.devices:
            self.assertNotIn(device.name, response.body.decode('utf-8'))


class EmailAddressTests(WebTest):

    def setUp(self):
        user = baker.make(User)

# Path: labshare/consumers.py
# class GPUInfoUpdater(WebsocketConsumer):
#     def connect(self):
#         self.user = self.scope['user']
#         self.device_name = self.scope['url_route']['kwargs']['device_name']
# 
#         device = Device.objects.get(name=self.device_name)
#         if device.can_be_used_by(self.user):
#             async_to_sync(self.channel_layer.group_add)(
#                 self.device_name,
#                 self.channel_name,
#             )
# 
#             publish_device_state(device.serialize(), self.channel_name)
# 
#             self.accept()
#         else:
#             self.close()
# 
#     def disconnect(self, message, **kwargs):
#         async_to_sync(self.channel_layer.group_discard)(
#             self.device_name,
#             self.channel_name,
#         )
# 
#     def update_info(self, event):
#         self.send(text_data=event['message'])
# 
# Path: labshare/models.py
# class Device(models.Model):
#     name = models.CharField(max_length=255)
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
# 
#     class Meta:
#         permissions = (
#             ('use_device', 'User/Group is allowed to use that device'),
#         )
# 
#     def __str__(self):
#         return self.name
# 
#     def can_be_used_by(self, user):
#         content_type = ContentType.objects.get_for_model(self)
#         permission_name = "{app}.use_{model}".format(app=content_type.app_label, model=content_type.model)
#         return user.has_perm(permission_name, self) or user.has_perm(permission_name)
# 
#     def serialize(self):
#         return {
#             'name': self.name,
#         }
# 
# class EmailAddress(models.Model):
#     user = models.ForeignKey(User, related_name="email_addresses", on_delete=models.CASCADE)
#     email = models.EmailField(max_length=255)
# 
#     def __str__(self):
#         return "{}: {}".format(self.user, self.email)
# 
# class GPU(models.Model):
#     uuid = models.CharField(max_length=255)
#     model_name = models.CharField(max_length=255)
#     reserved = models.BooleanField(default=False)
#     device = models.ForeignKey(Device, related_name='gpus', on_delete=models.CASCADE)
# 
#     def serialize(self):
#         return {
#             'uuid': self.uuid,
#             'model_name': self.model_name,
#             'reserved': self.reserved
#         }
# 
# Path: labshare/routing.py

# 
# Path: labshare/templatetags/icon.py
# @register.tag
# def icon(parser, token):
#     split = token.contents.split(' ')
#     if len(split) < 2:
#         return no_icon_error()
#     if len(split) > 2:
#         raise template.TemplateSyntaxError("too many arguments!")
#     icon_name = extract_string(token.contents.split(' ')[1])
# 
#     return IconNode(icon_name)
# 
# Path: labshare/utils.py
# def get_devices():
#     return [(device.name, device.name) for device in Device.objects.all()]
# 
# def publish_device_state(device_data, channel_name=None):
#     channel_layer = channels.layers.get_channel_layer()
#     name = device_data['name']
#     if 'gpus' not in device_data:
#         device_data['gpus'] = []
# 
#     if channel_name is None:
#         send_function = async_to_sync(channel_layer.group_send)
#     else:
#         send_function = async_to_sync(channel_layer.send)
#     send_function(channel_name if channel_name else name, {'type': 'update_info', 'message': json.dumps(device_data)})


# Path: labshare/tests.py
import copy
import datetime
import io
import json
import os
import random
import string
import time
import unittest.mock as mock
import uuid
import requests
from datetime import timedelta
from unittest import skipIf
from unittest.mock import Mock
from channels.layers import get_channel_layer
from channels.testing import ChannelsLiveServerTestCase, WebsocketCommunicator
from django import template
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.core import mail
from django.test import TestCase, override_settings, Client
from django.urls import reverse
from django_webtest import WebTest
from guardian.shortcuts import assign_perm
from guardian.utils import get_anonymous_user
from model_bakery import baker
from model_bakery.recipe import Recipe
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from labshare.consumers import GPUInfoUpdater
from labshare.models import Device, EmailAddress, GPU
from labshare.routing import application
from labshare.templatetags.icon import icon
from labshare.utils import get_devices, publish_device_state


        for device in self.devices[:-1]:
            assign_perm('use_device', self.student_group, device)

        self.staff_group = baker.make(Group, name="staff")
        self.staff_user.groups.add(self.staff_group)

        for device in self.devices:
            assign_perm('use_device', self.staff_group, device)

    def test_overview_correct(self):
        response = self.app.get(reverse('index'), user=self.user)
        response_text = response.body.decode('utf-8')
        for device in self.devices[:-1]:
            self.assertIn(device.name, response_text)
        self.assertNotIn(self.devices[-1].name, response_text)

        response = self.app.get(reverse("index"), user=self.staff_user)
        for device in self.devices:
            self.assertIn(device.name, response.body.decode('utf-8'))

        response = self.app.get(reverse("index"), user=get_anonymous_user())
        for device in self.devices:
            self.assertNotIn(device.name, response.body.decode('utf-8'))


class EmailAddressTests(WebTest):

    def setUp(self):
        user = baker.make(User)

        baker.make(EmailAddress, _quantity=5, user=user)