text:
/* load after build_application.js */

window.app.builders.EcmascriptDebugger || ( window.app.builders.EcmascriptDebugger = {} );

/**
  * @param {Object} service the service description of the according service on the host side
  */

window.app.builders.EcmascriptDebugger["5.0"] = function(service)
{
  var namespace = cls.EcmascriptDebugger && cls.EcmascriptDebugger["5.0"];
  var service_interface = window.services['ecmascript-debugger'];

  if(service_interface)
  {
    window.ObjectDataBase = new namespace.ObjectDataBase();
    namespace.Frame_inspection_data.prototype = ObjectDataBase;
    window.frame_inspection_data = new namespace.Frame_inspection_data();
    namespace.Node_dom_attrs.prototype = ObjectDataBase;
    window.node_dom_attrs = new namespace.Node_dom_attrs();
    namespace.Object_inspection_data.prototype = ObjectDataBase;
    window.object_inspection_data = new namespace.Object_inspection_data();

    window.runtimes = new namespace.Runtimes();
    window.runtimes.bind(service_interface);

    window.dom_data = new namespace.DOMData('dom');
    window.dom_data.bind(service_interface);
    window.stop_at = new namespace.StopAt();
    window.stop_at.bind(service_interface);
    window.host_tabs = new namespace.HostTabs();
    window.host_tabs.bind(service_interface);
    window.hostspotlighter = new namespace.Hostspotlighter();
    window.hostspotlighter.bind(service_interface);

    /* ECMA object inspection */
    namespace.InspectionView.prototype = ViewBase;
    new namespace.InspectionView('inspection', ui_strings.M_VIEW_LABEL_FRAME_INSPECTION, 'scroll');
    namespace.InspectionView.create_ui_widgets();

    /* DOM object inspection */
    namespace.DOMAttrsView.prototype = ViewBase;
    new namespace.DOMAttrsView('dom_attrs', ui_strings.M_VIEW_LABEL_DOM_ATTR, 'scroll dom-attrs');
    namespace.DOMAttrsView.create_ui_widgets();

    /*
      a namespace for all the followindg classes will only be created
      if needed to adjust them for an updated service version
    */

    window.runtime_onload_handler = new cls.RuntimeOnloadHandler();

    /* temporary export view */
    window.export_data = new cls.ExportData();
    new cls.ExportDataView('export_data', ui_strings.M_VIEW_LABEL_EXPORT, 'scroll export-data');

    /* commandline */
    cls.CommandLineView.prototype = ViewBase;
    new cls.CommandLineView('command_line', ui_strings.M_VIEW_LABEL_COMMAND_LINE, 'scroll', '', 'cmd-focus');
    cls.CndRtSelect.prototype = new CstSelect();
    new cls.CndRtSelect('cmd-runtime-select', 'cmd-line-runtimes');
    cls.CommandLineView.create_ui_widgets();

    /* JS source */
    window.simple_js_parser = new window.cls.SimpleJSParser();
    new cls.JsSourceView('js_source', ui_strings.M_VIEW_LABEL_SOURCE, 'scroll js-source');
    new cls.ScriptSelect('js-script-select', 'script-options');
    cls.JsSourceView.create_ui_widgets();

    /* Callstack */
    cls.CallstackView.prototype = ViewBase;
    new cls.CallstackView('callstack', ui_strings.M_VIEW_LABEL_CALLSTACK, 'scroll');

    /* Threads */
    cls.ThreadsView.prototype = ViewBase;
    new cls.ThreadsView('threads', ui_strings.M_VIEW_LABEL_THREAD_LOG, 'scroll threads');
    cls.ThreadsView.create_ui_widgets();

    /* DOM */
    cls.InspectableDOMNode = namespace.InspectableDOMNode;
    new cls.DOMInspectorActions('dom'); // the view id
    new cls.DOMInspectorKeyhandler('dom');
    new cls.DOMInspectorEditKeyhandler('dom');
    cls.DOMView.prototype = ViewBase;
    new cls.DOMView('dom', ui_strings.M_VIEW_LABEL_DOM, 'scroll dom');
    cls.DOMView.prototype.constructor = cls.DOMView;
    cls.DocumentSelect.prototype = new CstSelect();
    new cls.DocumentSelect('document-select', 'document-options');
    cls.DOMView.create_ui_widgets();

    /* Stylesheets */
    window.stylesheets = new cls.Stylesheets();
    cls.StylesheetsView.prototype = ViewBase;
    new cls.StylesheetsView('stylesheets', ui_strings.M_VIEW_LABEL_STYLESHEET, 'scroll stylesheets');
    cls.StylesheetSelect.prototype = new CstSelect();
    new cls.StylesheetSelect('stylesheet-select', 'stylesheet-options');
    cls.StylesheetsView.create_ui_widgets();

    /* CSS inspector */
    window.elementStyle = new cls.ElementStyle();
    cls.CSSInspectorView.prototype = ViewBase;
    new cls.CSSInspectorView('css-inspector', ui_strings.M_VIEW_LABEL_STYLES, 'scroll css-inspector');
    cls.CSSInspectorView.create_ui_widgets();
    new cls.ColorPickerView('color-selector', 'Color Picker', 'color-selector');

    /* Layout */
    window.elementLayout = new cls.ElementLayout();
    cls.CSSLayoutView.prototype = ViewBase;
    new cls.CSSLayoutView('css-layout', ui_strings.M_VIEW_LABEL_LAYOUT, 'scroll css-layout');

    /* storage objects and cookies */
    new cls.Namespace("storages");
    window.storages.add(new cls.LocalStorageData(
      'local_storage',
      'local-storage',
      ui_strings.M_VIEW_LABEL_LOCAL_STORAGE,
      'localStorage'));
    window.storages.add(new cls.LocalStorageData(
      'session_storage',
      'session-storage',
      ui_strings.M_VIEW_LABEL_SESSION_STORAGE,
      'sessionStorage'));
    window.storages.add(new cls.LocalStorageData(
      'widget_preferences',
      'widget-preferences',
      ui_strings.M_VIEW_LABEL_WIDGET_PREFERNCES,
      'widget.preferences'));
    window.storages.add(new cls.CookiesData(
      'cookies',
      'cookies',
      ui_strings.M_VIEW_LABEL_COOKIES));
    new cls.StorageView('local_storage', ui_strings.M_VIEW_LABEL_LOCAL_STORAGE, 'scroll');
    new cls.StorageView('session_storage', ui_strings.M_VIEW_LABEL_SESSION_STORAGE, 'scroll');
    new cls.StorageView('cookies', ui_strings.M_VIEW_LABEL_COOKIES, 'scroll');
    new cls.StorageView('widget_preferences', ui_strings.M_VIEW_LABEL_WIDGET_PREFERNCES, 'scroll');

    /* the following views must be created to get entry in the Settings tab */

    /* Environment */
    cls.EnvironmentView.prototype = ViewBase;
    new cls.EnvironmentView('environment', ui_strings.M_VIEW_LABEL_ENVIRONMENT, 'scroll');
    cls.EnvironmentView.create_ui_widgets();

    /* About */
    cls.AboutView.prototype = ViewBase;
    new cls.AboutView('about', 'About', 'scroll');
    cls.AboutView.create_ui_widgets();

    /* Hostspotlighter */
    cls.HostSpotlightView.prototype = ViewBase;
    new cls.HostSpotlightView('host-spotlight', ui_strings.S_LABEL_SPOTLIGHT_TITLE, '');
    cls.HostSpotlightView.create_ui_widgets();

    /* main view doesn't really exist */
    cls.MainView.create_ui_widgets();

  }

}


text:
from __future__ import print_function
import os
import re
import sys
import logging
import getpass
import random
import string
import traceback
import inspect
import pickle
import platform
from time import sleep

import py
import pytest
import requests
from six import print_ as print
from six import integer_types

if platform.python_version() < '3':
    try:
        import unittest2 as unittest
    except ImportError:
        import pip

        if hasattr(sys, 'real_prefix'):
            pip.main(['install', '--upgrade', 'unittest2'])
        else:
            pip.main(['install', '--upgrade', '--user', 'unittest2'])
        import unittest2 as unittest
else:
    import unittest

cmd_folder = os.path.abspath(os.path.join(os.path.split(inspect.getfile(
    inspect.currentframe()))[0], ".."))
if cmd_folder not in sys.path:
    sys.path.insert(0, cmd_folder)

import jira
from jira import Role, Issue, JIRA, JIRAError, Project
from jira.resources import Resource, cls_for_resource

TEST_ROOT = os.path.dirname(__file__)
TEST_ICON_PATH = os.path.join(TEST_ROOT, 'icon.png')
TEST_ATTACH_PATH = os.path.join(TEST_ROOT, 'tests.py')

OAUTH = False
CONSUMER_KEY = 'oauth-consumer'
KEY_CERT_FILE = '/home/bspeakmon/src/atlassian-oauth-examples/rsa.pem'
KEY_CERT_DATA = None
try:
    with open(KEY_CERT_FILE, 'r') as cert:
        KEY_CERT_DATA = cert.read()
    OAUTH = True
except:
    pass

if 'CI_JIRA_URL' in os.environ:
    not_on_custom_jira_instance = pytest.mark.skipif(True, reason="Not applicable for custom JIRA instance")
    print('Picked up custom JIRA engine.')
else:
    def noop(arg):
        return arg
    not_on_custom_jira_instance = noop

def rndstr():
    return ''.join(random.sample(string.ascii_letters, 6))

def rndpassword():
    # generates a password of lengh 14
    s = ''.join(random.sample(string.ascii_uppercase, 5)) + \
        ''.join(random.sample(string.ascii_lowercase, 5)) + \
        ''.join(random.sample(string.digits, 2)) + \
        ''.join(random.sample('~`!@#$%^&*()_+-=[]\\{}|;\':<>?,./', 2))
    return ''.join(random.sample(s, len(s)))

class Singleton(type):

    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None

    def __call__(cls, *args, **kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)
        return cls.instance

class JiraTestManager(object):
    """
    Used to instantiate and populate the JIRA instance with data used by the unit tests.

    Attributes:
        CI_JIRA_ADMIN (str): Admin user account name.
        CI_JIRA_USER (str): Limited user account name.
        max_retries (int): number of retries to perform for recoverable HTTP errors.
    """
    # __metaclass__ = Singleton

    # __instance = None
    #
    # Singleton implementation
    # def __new__(cls, *args, **kwargs):
    #     if not cls.__instance:
    #         cls.__instance = super(JiraTestManager, cls).__new__(
    #                             cls, *args, **kwargs)
    #     return cls.__instance

    #  Implementing some kind of Singleton, to prevent test initialization
    # http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/33201#33201
    __shared_state = {}

    def __init__(self):
        self.__dict__ = self.__shared_state

        if not self.__dict__:
            self.initialized = 0

            try:

                if 'CI_JIRA_URL' in os.environ:
                    self.CI_JIRA_URL = os.environ['CI_JIRA_URL']
                    self.max_retries = 5
                else:
                    self.CI_JIRA_URL = "https://pycontribs.atlassian.net"
                    self.max_retries = 5

                if 'CI_JIRA_ADMIN' in os.environ:
                    self.CI_JIRA_ADMIN = os.environ['CI_JIRA_ADMIN']
                else:
                    self.CI_JIRA_ADMIN = 'ci-admin'

                if 'CI_JIRA_ADMIN_PASSWORD' in os.environ:
                    self.CI_JIRA_ADMIN_PASSWORD = os.environ[
                        'CI_JIRA_ADMIN_PASSWORD']
                else:
                    self.CI_JIRA_ADMIN_PASSWORD = 'sd4s3dgec5fhg4tfsds3434'

                if 'CI_JIRA_USER' in os.environ:
                    self.CI_JIRA_USER = os.environ['CI_JIRA_USER']
                else:
                    self.CI_JIRA_USER = 'ci-user'

                if 'CI_JIRA_USER_PASSWORD' in os.environ:
                    self.CI_JIRA_USER_PASSWORD = os.environ[
                        'CI_JIRA_USER_PASSWORD']
                else:
                    self.CI_JIRA_USER_PASSWORD = 'sd4s3dgec5fhg4tfsds3434'

                self.CI_JIRA_ISSUE = os.environ.get('CI_JIRA_ISSUE', 'Bug')

                if OAUTH:
                    self.jira_admin = JIRA(oauth={
                        'access_token': 'hTxcwsbUQiFuFALf7KZHDaeAJIo3tLUK',
                        'access_token_secret': 'aNCLQFP3ORNU6WY7HQISbqbhf0UudDAf',
                        'consumer_key': CONSUMER_KEY,
                        'key_cert': KEY_CERT_DATA,
                    })
                else:
                    if self.CI_JIRA_ADMIN:
                        self.jira_admin = JIRA(self.CI_JIRA_URL, basic_auth=(self.CI_JIRA_ADMIN,
                                                                             self.CI_JIRA_ADMIN_PASSWORD),
                                               logging=False, validate=True, max_retries=self.max_retries)
                    else:
                        self.jira_admin = JIRA(self.CI_JIRA_URL, validate=True,
                                               logging=False, max_retries=self.max_retries)
                if self.jira_admin.current_user() != self.CI_JIRA_ADMIN:
                    # self.jira_admin.
                    self.initialized = 1
                    sys.exit(3)

                if OAUTH:
                    self.jira_sysadmin = JIRA(oauth={
                        'access_token': '4ul1ETSFo7ybbIxAxzyRal39cTrwEGFv',
                        'access_token_secret':
                            'K83jBZnjnuVRcfjBflrKyThJa0KSjSs2',
                        'consumer_key': CONSUMER_KEY,
                        'key_cert': KEY_CERT_DATA,
                    }, logging=False, max_retries=self.max_retries)
                else:
                    if self.CI_JIRA_ADMIN:
                        self.jira_sysadmin = JIRA(self.CI_JIRA_URL,
                                                  basic_auth=(self.CI_JIRA_ADMIN,
                                                              self.CI_JIRA_ADMIN_PASSWORD),
                                                  logging=False, validate=True, max_retries=self.max_retries)
                    else:
                        self.jira_sysadmin = JIRA(self.CI_JIRA_URL,
                                                  logging=False, max_retries=self.max_retries)

                if OAUTH:
                    self.jira_normal = JIRA(oauth={
                        'access_token': 'ZVDgYDyIQqJY8IFlQ446jZaURIz5ECiB',
                        'access_token_secret':
                            '5WbLBybPDg1lqqyFjyXSCsCtAWTwz1eD',
                        'consumer_key': CONSUMER_KEY,
                        'key_cert': KEY_CERT_DATA,
                    })
                else:
                    if self.CI_JIRA_ADMIN:
                        self.jira_normal = JIRA(self.CI_JIRA_URL,
                                                basic_auth=(self.CI_JIRA_USER,
                                                            self.CI_JIRA_USER_PASSWORD),
                                                validate=True, logging=False, max_retries=self.max_retries)
                    else:
                        self.jira_normal = JIRA(self.CI_JIRA_URL,
                                                validate=True, logging=False, max_retries=self.max_retries)

                # now we need some data to start with for the tests

                # jira project key is max 10 chars, no letter.
                # [0] always "Z"
                # [1-6] username running the tests (hope we will not collide)
                # [7-8] python version A=0, B=1,..
                # [9] A,B -- we may need more than one project

                prefix = 'Z' + (re.sub("[^A-Z]", "",
                                       getpass.getuser().upper()))[0:6] + \
                         chr(ord('A') + sys.version_info[0]) + \
                         chr(ord('A') + sys.version_info[1])

                self.project_a = prefix + 'A'  # old XSS
                self.project_a_name = "Test user=%s python=%s.%s A" \
                                      % (getpass.getuser(), sys.version_info[0],
                                         sys.version_info[1])
                self.project_b_name = "Test user=%s python=%s.%s B" \
                                      % (getpass.getuser(), sys.version_info[0],
                                         sys.version_info[1])
                self.project_b = prefix + 'B'  # old BULK

                # TODO: fin a way to prevent SecurityTokenMissing for On Demand
                # https://jira.atlassian.com/browse/JRA-39153
                try:
                    self.jira_admin.project(self.project_a)
                except Exception as e:
                    logging.warning(e)
                    pass
                else:
                    self.jira_admin.delete_project(self.project_a)

                try:
                    self.jira_admin.project(self.project_b)
                except Exception as e:
                    logging.warning(e)
                    pass
                else:
                    self.jira_admin.delete_project(self.project_b)

                # try:
                self.jira_admin.create_project(self.project_a,
                                               self.project_a_name)
                self.project_a_id = self.jira_admin.project(self.project_a).id
                # except Exception as e:
                #    logging.warning("Got %s" % e)
                # try:
                # assert self.jira_admin.create_project(self.project_b,
                # self.project_b_name) is  True, "Failed to create %s" %
                # self.project_b
                self.jira_admin.create_project(self.project_b,
                                               self.project_b_name)
                # except Exception as e:
                #    logging.warning("Got %s" % e)

                self.project_b_issue1_obj = self.jira_admin.create_issue(project=self.project_b,
                                                                         summary='issue 1 from %s'
                                                                                % self.project_b,
                                                                         issuetype=self.CI_JIRA_ISSUE)
                self.project_b_issue1 = self.project_b_issue1_obj.key

                self.project_b_issue2_obj = self.jira_admin.create_issue(project=self.project_b,
                                                                         summary='issue 2 from %s'
                                                                                % self.project_b,
                                                                         issuetype={'name': self.CI_JIRA_ISSUE})
                self.project_b_issue2 = self.project_b_issue2_obj.key

                self.project_b_issue3_obj = self.jira_admin.create_issue(project=self.project_b,
                                                                         summary='issue 3 from %s'
                                                                                % self.project_b,
                                                                         issuetype={'name': self.CI_JIRA_ISSUE})
                self.project_b_issue3 = self.project_b_issue3_obj.key

            except Exception as e:
                # exc_type, exc_value, exc_traceback = sys.exc_info()
                formatted_lines = traceback.format_exc().splitlines()
                msg = "Basic test setup failed: %s\n\t%s" % (
                    e, "\n\t".join(formatted_lines))
                logging.fatal(msg)
                self.initialized = 1
                py.test.exit("FATAL")

            self.initialized = 1

        else:
            # already exist but we need to be sure it was initialized
            counter = 0
            while not self.initialized:
                sleep(1)
                counter += 1
                if counter > 60:
                    logging.fatal("Something is clearly not right with " +
                                  "initialization, killing the tests to prevent a " +
                                  "deadlock.")
                    sys.exit(3)

def find_by_key(seq, key):
    for seq_item in seq:
        if seq_item['key'] == key:
            return seq_item

def find_by_key_value(seq, key):
    for seq_item in seq:
        if seq_item.key == key:
            return seq_item

def find_by_id(seq, id):
    for seq_item in seq:
        if seq_item.id == id:
            return seq_item

def find_by_name(seq, name):
    for seq_item in seq:
        if seq_item['name'] == name:
            return seq_item

class UniversalResourceTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.test_manager = JiraTestManager()

    def test_universal_find_existing_resource(self):
        resource = self.jira.find('issue/{0}',
                                  self.test_manager.project_b_issue1)
        issue = self.jira.issue(self.test_manager.project_b_issue1)
        self.assertEqual(resource.self, issue.self)
        self.assertEqual(resource.key, issue.key)

    def test_find_invalid_resource_raises_exception(self):
        with self.assertRaises(JIRAError) as cm:
            self.jira.find('woopsydoodle/{0}', '666')

        ex = cm.exception
        # py26,27,34 gets 404 but on py33 gets 400
        assert ex.status_code in [400, 404]
        self.assertIsNotNone(ex.text)
        self.assertRegex(ex.url, '^https?://.*/rest/api/(2|latest)/woopsydoodle/666$')

    def test_pickling_resource(self):
        resource = self.jira.find('issue/{0}',
                                  self.test_manager.project_b_issue1)

        pickled = pickle.dumps(resource.raw)
        unpickled = pickle.loads(pickled)
        cls = cls_for_resource(unpickled['self'])
        unpickled_instance = cls(self.jira._options, self.jira._session, raw=pickle.loads(pickled))
        self.assertEqual(resource.key, unpickled_instance.key)
        self.assertTrue(resource == unpickled_instance)

class ResourceTests(unittest.TestCase):

    def setUp(self):
        pass

    def test_cls_for_resource(self):
        self.assertEqual(cls_for_resource('https://jira.atlassian.com/rest/\
                api/latest/issue/JRA-1330'), Issue)
        self.assertEqual(cls_for_resource('http://localhost:2990/jira/rest/\
                api/latest/project/BULK'), Project)
        self.assertEqual(cls_for_resource('http://imaginary-jira.com/rest/\
                api/latest/project/IMG/role/10002'), Role)
        self.assertEqual(cls_for_resource('http://customized-jira.com/rest/\
                plugin-resource/4.5/json/getMyObject'), Resource)

class ApplicationPropertiesTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_application_properties(self):
        props = self.jira.application_properties()
        for p in props:
            self.assertIsInstance(p, dict)
            self.assertTrue(set(p.keys()).issuperset(set(['type', 'name', 'value', 'key', 'id'])))

    def test_application_property(self):
        clone_prefix = self.jira.application_properties(
            key='jira.lf.text.headingcolour')
        self.assertEqual(clone_prefix['value'], '#292929')

    def test_set_application_property(self):
        prop = 'jira.lf.favicon.hires.url'
        valid_value = '/jira-favicon-hires.png'
        invalid_value = '/Tjira-favicon-hires.png'
        counter = 0

        while self.jira.application_properties(key=prop)['value'] != valid_value and counter < 3:
            if counter:
                sleep(10)
            self.jira.set_application_property(prop, invalid_value)
            self.assertEqual(self.jira.application_properties(key=prop)['value'],
                             invalid_value)
            self.jira.set_application_property(prop, valid_value)
            self.assertEqual(self.jira.application_properties(key=prop)['value'],
                             valid_value)
            counter += 1

    def test_setting_bad_property_raises(self):
        prop = 'random.nonexistent.property'
        self.assertRaises(JIRAError, self.jira.set_application_property, prop,
                          '666')

class AttachmentTests(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = JiraTestManager().jira_admin
        self.project_b = self.test_manager.project_b
        self.issue_1 = self.test_manager.project_b_issue1
        self.attachment = None

    def test_0_attachment_meta(self):
        meta = self.jira.attachment_meta()
        self.assertTrue(meta['enabled'])
        self.assertEqual(meta['uploadLimit'], 10485760)

    def test_1_add_remove_attachment(self):
        issue = self.jira.issue(self.issue_1)
        self.attachment = self.jira.add_attachment(issue, open(TEST_ATTACH_PATH, 'rb'),
                                                   "new test attachment")
        new_attachment = self.jira.attachment(self.attachment.id)
        msg = "attachment %s of issue %s" % (new_attachment.__dict__, issue)
        self.assertEqual(
            new_attachment.filename, 'new test attachment', msg=msg)
        self.assertEqual(
            new_attachment.size, os.path.getsize(TEST_ATTACH_PATH), msg=msg)
        assert self.attachment.delete() is None

class ComponentTests(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = JiraTestManager().jira_admin
        self.project_b = self.test_manager.project_b
        self.issue_1 = self.test_manager.project_b_issue1
        self.issue_2 = self.test_manager.project_b_issue2

    def test_2_create_component(self):
        proj = self.jira.project(self.project_b)
        name = "project-%s-component-%s" % (proj, rndstr())
        component = self.jira.create_component(name,
                                               proj, description='test!!', assigneeType='COMPONENT_LEAD',
                                               isAssigneeTypeValid=False)
        self.assertEqual(component.name, name)
        self.assertEqual(component.description, 'test!!')
        self.assertEqual(component.assigneeType, 'COMPONENT_LEAD')
        self.assertFalse(component.isAssigneeTypeValid)
        component.delete()

        for c in self.jira.project_components(self.project_b):
            print(c)

    # COmponents field can't be modified from issue.update
    #    def test_component_count_related_issues(self):
    #        component = self.jira.create_component('PROJECT_B_TEST',self.project_b, description='test!!',
    #                                               assigneeType='COMPONENT_LEAD', isAssigneeTypeValid=False)
    #        issue1 = self.jira.issue(self.issue_1)
    #        issue2 = self.jira.issue(self.issue_2)
    #        (issue1.update ({'components': ['PROJECT_B_TEST']}))
    #        (issue2.update (components = ['PROJECT_B_TEST']))
    #        issue_count = self.jira.component_count_related_issues(component.id)
    #        self.assertEqual(issue_count, 2)
    #        component.delete()

    def test_3_update(self):
        try:
            components = self.jira.project_components(self.project_b)
            for component in components:
                if component.name == 'To be updated':
                    component.delete()
                    break
        except Exception as e:
            # We ignore errors as this code intends only to prepare for
            # component creation
            pass

        name = 'component-' + rndstr()

        component = self.jira.create_component(name,
                                               self.project_b, description='stand by!',
                                               leadUserName=self.test_manager.CI_JIRA_ADMIN)
        name = 'renamed-' + name
        component.update(name=name, description='It is done.',
                         leadUserName=self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(component.name, name)
        self.assertEqual(component.description, 'It is done.')
        self.assertEqual(component.lead.name, self.test_manager.CI_JIRA_ADMIN)
        component.delete()

    def test_4_delete(self):
        component = self.jira.create_component('To be deleted',
                                               self.project_b, description='not long for this world')
        myid = component.id
        component.delete()
        self.assertRaises(JIRAError, self.jira.component, myid)

class CustomFieldOptionTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    @not_on_custom_jira_instance
    def test_custom_field_option(self):
        option = self.jira.custom_field_option('10001')
        self.assertEqual(option.value, 'To Do')

@not_on_custom_jira_instance
class DashboardTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_dashboards(self):
        dashboards = self.jira.dashboards()
        self.assertEqual(len(dashboards), 3)

    def test_dashboards_filter(self):
        dashboards = self.jira.dashboards(filter='my')
        self.assertEqual(len(dashboards), 2)
        self.assertEqual(dashboards[0].id, '10101')

    def test_dashboards_startat(self):
        dashboards = self.jira.dashboards(startAt=1, maxResults=1)
        self.assertEqual(len(dashboards), 1)

    def test_dashboards_maxresults(self):
        dashboards = self.jira.dashboards(maxResults=1)
        self.assertEqual(len(dashboards), 1)

    def test_dashboard(self):
        dashboard = self.jira.dashboard('10101')
        self.assertEqual(dashboard.id, '10101')
        self.assertEqual(dashboard.name, 'Another test dashboard')

@not_on_custom_jira_instance
class FieldsTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_fields(self):
        fields = self.jira.fields()
        self.assertGreater(len(fields), 10)

class FilterTests(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = JiraTestManager().jira_admin
        self.project_b = self.test_manager.project_b
        self.issue_1 = self.test_manager.project_b_issue1
        self.issue_2 = self.test_manager.project_b_issue2

    def test_filter(self):
        jql = "project = %s and component is not empty" % self.project_b
        name = 'same filter ' + rndstr()
        myfilter = self.jira.create_filter(name=name,
                                           description="just some new test filter", jql=jql,
                                           favourite=False)
        self.assertEqual(myfilter.name, name)
        self.assertEqual(myfilter.owner.name, self.test_manager.CI_JIRA_ADMIN)
        myfilter.delete()

    def test_favourite_filters(self):
        # filters = self.jira.favourite_filters()
        jql = "project = %s and component is not empty" % self.project_b
        name = "filter-to-fav-" + rndstr()
        myfilter = self.jira.create_filter(name=name,
                                           description="just some new test filter", jql=jql,
                                           favourite=True)
        new_filters = self.jira.favourite_filters()

        assert name in [f.name for f in new_filters]
        myfilter.delete()

@not_on_custom_jira_instance
class GroupsTest(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = self.test_manager.jira_admin

    def test_groups(self):
        groups = self.jira.groups()
        self.assertGreater(len(groups), 0)

    def test_groups_for_users(self):
        groups = self.jira.groups('jira-users')
        self.assertGreater(len(groups), 0)

class IssueTests(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = JiraTestManager().jira_admin
        self.jira_normal = self.test_manager.jira_normal
        self.project_b = self.test_manager.project_b
        self.project_a = self.test_manager.project_a
        self.issue_1 = self.test_manager.project_b_issue1
        self.issue_2 = self.test_manager.project_b_issue2
        self.issue_3 = self.test_manager.project_b_issue3

    def test_issue(self):
        issue = self.jira.issue(self.issue_1)
        self.assertEqual(issue.key, self.issue_1)
        self.assertEqual(issue.fields.summary,
                         'issue 1 from %s' % self.project_b)

    @unittest.skip("disabled as it seems to be ignored by jira, returning all")
    def test_issue_field_limiting(self):
        issue = self.jira.issue(self.issue_2, fields='summary,comment')
        self.assertEqual(issue.fields.summary,
                         'issue 2 from %s' % self.project_b)
        comment1 = self.jira.add_comment(issue, 'First comment')
        comment2 = self.jira.add_comment(issue, 'Second comment')
        comment3 = self.jira.add_comment(issue, 'Third comment')
        self.jira.issue(self.issue_2, fields='summary,comment')
        logging.warning(issue.raw['fields'])
        self.assertFalse(hasattr(issue.fields, 'reporter'))
        self.assertFalse(hasattr(issue.fields, 'progress'))
        comment1.delete()
        comment2.delete()
        comment3.delete()

    def test_issue_equal(self):
        issue1 = self.jira.issue(self.issue_1)
        issue2 = self.jira.issue(self.issue_2)
        issues = self.jira.search_issues('key=%s' % self.issue_1)
        self.assertTrue(issue1 == issues[0])
        self.assertFalse(issue2 == issues[0])

    def test_issue_expandos(self):
        issue = self.jira.issue(self.issue_1, expand='editmeta,schema')
        self.assertTrue(hasattr(issue, 'editmeta'))
        self.assertTrue(hasattr(issue, 'schema'))
        # testing for changelog is not reliable because it may exist or not based on test order
        # self.assertFalse(hasattr(issue, 'changelog'))

    @not_on_custom_jira_instance
    def test_create_issue_with_fieldargs(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue created', description='blahery',
                                       issuetype={'name': 'Bug'})  # customfield_10022='XSS'
        self.assertEqual(issue.fields.summary, 'Test issue created')
        self.assertEqual(issue.fields.description, 'blahery')
        self.assertEqual(issue.fields.issuetype.name, 'Bug')
        self.assertEqual(issue.fields.project.key, self.project_b)
        #self.assertEqual(issue.fields.customfield_10022, 'XSS')
        issue.delete()

    @not_on_custom_jira_instance
    def test_create_issue_with_fielddict(self):
        fields = {
            'project': {
                'key': self.project_b
            },
            'summary': 'Issue created from field dict',
            'description': "Some new issue for test",
            'issuetype': {
                'name': 'Bug'
            },
            #'customfield_10022': 'XSS',
            'priority': {
                'name': 'Major'
            }
        }
        issue = self.jira.create_issue(fields=fields)
        self.assertEqual(issue.fields.summary,
                         'Issue created from field dict')
        self.assertEqual(issue.fields.description, "Some new issue for test")
        self.assertEqual(issue.fields.issuetype.name, 'Bug')
        self.assertEqual(issue.fields.project.key, self.project_b)
        #self.assertEqual(issue.fields.customfield_10022, 'XSS')
        self.assertEqual(issue.fields.priority.name, 'Major')
        issue.delete()

    @not_on_custom_jira_instance
    def test_create_issue_without_prefetch(self):
        issue = self.jira.create_issue(prefetch=False,
                                       project=self.project_b,
                                       summary='Test issue created',
                                       description='blahery', issuetype={'name': 'Bug'}
                                       )  # customfield_10022='XSS'

        assert hasattr(issue, 'self')
        assert hasattr(issue, 'raw')
        assert 'fields' not in issue.raw
        issue.delete()

    @not_on_custom_jira_instance
    def test_update_with_fieldargs(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue for updating',
                                       description='Will be updated shortly',
                                       issuetype={'name': 'Bug'})
        # customfield_10022='XSS')
        issue.update(summary='Updated summary', description='Now updated',
                     issuetype={'name': 'Improvement'})
        self.assertEqual(issue.fields.summary, 'Updated summary')
        self.assertEqual(issue.fields.description, 'Now updated')
        self.assertEqual(issue.fields.issuetype.name, 'Improvement')
        #self.assertEqual(issue.fields.customfield_10022, 'XSS')
        self.assertEqual(issue.fields.project.key, self.project_b)
        issue.delete()

    @not_on_custom_jira_instance
    def test_update_with_fielddict(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue for updating', description='Will be updated shortly',
                                       issuetype={'name': 'Bug'})
        fields = {
            'summary': 'Issue is updated',
            'description': "it sure is",
            'issuetype': {
                'name': 'Improvement'
            },
            #'customfield_10022': 'DOC',
            'priority': {
                'name': 'Major'
            }
        }
        issue.update(fields=fields)
        self.assertEqual(issue.fields.summary, 'Issue is updated')
        self.assertEqual(issue.fields.description, 'it sure is')
        self.assertEqual(issue.fields.issuetype.name, 'Improvement')
        #self.assertEqual(issue.fields.customfield_10022, 'DOC')
        self.assertEqual(issue.fields.priority.name, 'Major')
        issue.delete()

    def test_update_with_label(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue for updating labels', description='Label testing',
                                       issuetype=self.test_manager.CI_JIRA_ISSUE)

        labelarray = ['testLabel']
        fields = {
            'labels': labelarray
        }

        issue.update(fields=fields)
        self.assertEqual(issue.fields.labels, ['testLabel'])

    def test_update_with_bad_label(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue for updating labels', description='Label testing',
                                       issuetype=self.test_manager.CI_JIRA_ISSUE)

        issue.fields.labels.append('this should not work')

        fields = {
            'labels': issue.fields.labels
        }

        self.assertRaises(JIRAError, issue.update, fields=fields)

    def test_delete(self):
        issue = self.jira.create_issue(project=self.project_b,
                                       summary='Test issue created',
                                       description='Not long for this world',
                                       issuetype=self.test_manager.CI_JIRA_ISSUE)
        key = issue.key
        issue.delete()
        self.assertRaises(JIRAError, self.jira.issue, key)

    @not_on_custom_jira_instance
    def test_createmeta(self):
        meta = self.jira.createmeta()
        ztravisdeb_proj = find_by_key(meta['projects'], self.project_b)
        # we assume that this project should allow at least one issue type
        self.assertGreaterEqual(len(ztravisdeb_proj['issuetypes']), 1)

    @not_on_custom_jira_instance
    def test_createmeta_filter_by_projectkey_and_name(self):
        meta = self.jira.createmeta(projectKeys=self.project_b,
                                    issuetypeNames='Bug')
        self.assertEqual(len(meta['projects']), 1)
        self.assertEqual(len(meta['projects'][0]['issuetypes']), 1)

    @not_on_custom_jira_instance
    def test_createmeta_filter_by_projectkeys_and_name(self):
        meta = self.jira.createmeta(projectKeys=(self.project_a,
                                                 self.project_b), issuetypeNames='Improvement')
        self.assertEqual(len(meta['projects']), 2)
        for project in meta['projects']:
            self.assertEqual(len(project['issuetypes']), 1)

    @not_on_custom_jira_instance
    def test_createmeta_filter_by_id(self):
        projects = self.jira.projects()
        proja = find_by_key_value(projects, self.project_a)
        projb = find_by_key_value(projects, self.project_b)
        meta = self.jira.createmeta(projectIds=(proja.id, projb.id),
                                    issuetypeIds=('3', '4', '5'))
        self.assertEqual(len(meta['projects']), 2)
        for project in meta['projects']:
            self.assertEqual(len(project['issuetypes']), 3)

    def test_createmeta_expando(self):
        # limit to SCR project so the call returns promptly
        meta = self.jira.createmeta(projectKeys=self.project_b,
                                    expand='projects.issuetypes.fields')
        self.assertTrue('fields' in meta['projects'][0]['issuetypes'][0])

    def test_assign_issue(self):
        self.assertTrue(self.jira.assign_issue(self.issue_1, self.test_manager.CI_JIRA_ADMIN))
        self.assertEqual(self.jira.issue(self.issue_1).fields.assignee.name,
                         self.test_manager.CI_JIRA_ADMIN)

    def test_assign_issue_with_issue_obj(self):
        issue = self.jira.issue(self.issue_1)
        x = self.jira.assign_issue(issue, self.test_manager.CI_JIRA_ADMIN)
        self.assertTrue(x)
        self.assertEqual(self.jira.issue(self.issue_1).fields.assignee.name,
                         self.test_manager.CI_JIRA_ADMIN)

    def test_assign_to_bad_issue_raises(self):
        self.assertRaises(JIRAError, self.jira.assign_issue, 'NOPE-1',
                          'notauser')

    def test_comments(self):
        for issue in [self.issue_1, self.jira.issue(self.issue_2)]:
            self.jira.issue(issue)
            comment1 = self.jira.add_comment(issue, 'First comment')
            comment2 = self.jira.add_comment(issue, 'Second comment')
            comments = self.jira.comments(issue)
            assert comments[0].body == 'First comment'
            assert comments[1].body == 'Second comment'
            comment1.delete()
            comment2.delete()
            comments = self.jira.comments(issue)
            assert len(comments) == 0

    def test_add_comment(self):
        comment = self.jira.add_comment(self.issue_3, 'a test comment!',
                                        visibility={'type': 'role', 'value': 'Administrators'})
        self.assertEqual(comment.body, 'a test comment!')
        self.assertEqual(comment.visibility.type, 'role')
        self.assertEqual(comment.visibility.value, 'Administrators')
        comment.delete()

    def test_add_comment_with_issue_obj(self):
        issue = self.jira.issue(self.issue_3)
        comment = self.jira.add_comment(issue, 'a new test comment!',
                                        visibility={'type': 'role', 'value': 'Administrators'})
        self.assertEqual(comment.body, 'a new test comment!')
        self.assertEqual(comment.visibility.type, 'role')
        self.assertEqual(comment.visibility.value, 'Administrators')
        comment.delete()

    def test_update_comment(self):
        comment = self.jira.add_comment(self.issue_3, 'updating soon!')
        comment.update(body='updated!')
        self.assertEqual(comment.body, 'updated!')
        # self.assertEqual(comment.visibility.type, 'role')
        # self.assertEqual(comment.visibility.value, 'Administrators')
        comment.delete()

    def test_editmeta(self):
        for i in (self.issue_1, self.issue_2):
            meta = self.jira.editmeta(i)
            self.assertTrue('assignee' in meta['fields'])
            self.assertTrue('attachment' in meta['fields'])
            self.assertTrue('comment' in meta['fields'])
            self.assertTrue('components' in meta['fields'])
            self.assertTrue('description' in meta['fields'])
            self.assertTrue('duedate' in meta['fields'])
            self.assertTrue('environment' in meta['fields'])
            self.assertTrue('fixVersions' in meta['fields'])
            self.assertTrue('issuelinks' in meta['fields'])
            self.assertTrue('issuetype' in meta['fields'])
            self.assertTrue('labels' in meta['fields'])
            self.assertTrue('versions' in meta['fields'])

    # Nothing from remote link works
    #    def test_remote_links(self):
    #        self.jira.add_remote_link ('ZTRAVISDEB-3', globalId='python-test:story.of.horse.riding',
    #        links = self.jira.remote_links('QA-44')
    #        self.assertEqual(len(links), 1)
    #        links = self.jira.remote_links('BULK-1')
    #        self.assertEqual(len(links), 0)
    #
    #    @unittest.skip("temporary disabled")
    #    def test_remote_links_with_issue_obj(self):
    #        issue = self.jira.issue('QA-44')
    #        links = self.jira.remote_links(issue)
    #        self.assertEqual(len(links), 1)
    #        issue = self.jira.issue('BULK-1')
    #        links = self.jira.remote_links(issue)
    #        self.assertEqual(len(links), 0)
    #
    #    @unittest.skip("temporary disabled")
    #    def test_remote_link(self):
    #        link = self.jira.remote_link('QA-44', '10000')
    #        self.assertEqual(link.id, 10000)
    #        self.assertTrue(hasattr(link, 'globalId'))
    #        self.assertTrue(hasattr(link, 'relationship'))
    #
    #    @unittest.skip("temporary disabled")
    #    def test_remote_link_with_issue_obj(self):
    #        issue = self.jira.issue('QA-44')
    #        link = self.jira.remote_link(issue, '10000')
    #        self.assertEqual(link.id, 10000)
    #        self.assertTrue(hasattr(link, 'globalId'))
    #        self.assertTrue(hasattr(link, 'relationship'))
    #
    #    @unittest.skip("temporary disabled")
    #    def test_add_remote_link(self):
    #        link = self.jira.add_remote_link('BULK-3', globalId='python-test:story.of.horse.riding',
    #                                         object={'url': 'http://google.com', 'title': 'googlicious!'},
    #                                         application={'name': 'far too silly', 'type': 'sketch'}, relationship='mousebending')
    # creation response doesn't include full remote link info, so we fetch it again using the new internal ID
    #        link = self.jira.remote_link('BULK-3', link.id)
    #        self.assertEqual(link.application.name, 'far too silly')
    #        self.assertEqual(link.application.type, 'sketch')
    #        self.assertEqual(link.object.url, 'http://google.com')
    #        self.assertEqual(link.object.title, 'googlicious!')
    #        self.assertEqual(link.relationship, 'mousebending')
    #        self.assertEqual(link.globalId, 'python-test:story.of.horse.riding')
    #
    #    @unittest.skip("temporary disabled")
    #    def test_add_remote_link_with_issue_obj(self):
    #        issue = self.jira.issue('BULK-3')
    #        link = self.jira.add_remote_link(issue, globalId='python-test:story.of.horse.riding',
    #                                         object={'url': 'http://google.com', 'title': 'googlicious!'},
    #                                         application={'name': 'far too silly', 'type': 'sketch'}, relationship='mousebending')
    # creation response doesn't include full remote link info, so we fetch it again using the new internal ID
    #        link = self.jira.remote_link(issue, link.id)
    #        self.assertEqual(link.application.name, 'far too silly')
    #        self.assertEqual(link.application.type, 'sketch')
    #        self.assertEqual(link.object.url, 'http://google.com')
    #        self.assertEqual(link.object.title, 'googlicious!')
    #        self.assertEqual(link.relationship, 'mousebending')
    #        self.assertEqual(link.globalId, 'python-test:story.of.horse.riding')
    #
    #    @unittest.skip("temporary disabled")
    #    def test_update_remote_link(self):
    #        link = self.jira.add_remote_link('BULK-3', globalId='python-test:story.of.horse.riding',
    #                                         object={'url': 'http://google.com', 'title': 'googlicious!'},
    #                                         application={'name': 'far too silly', 'type': 'sketch'}, relationship='mousebending')
    # creation response doesn't include full remote link info, so we fetch it again using the new internal ID
    #        link = self.jira.remote_link('BULK-3', link.id)
    #        link.update(object={'url': 'http://yahoo.com', 'title': 'yahooery'}, globalId='python-test:updated.id',
    #                    relationship='cheesing')
    #        self.assertEqual(link.globalId, 'python-test:updated.id')
    #        self.assertEqual(link.relationship, 'cheesing')
    #        self.assertEqual(link.object.url, 'http://yahoo.com')
    #        self.assertEqual(link.object.title, 'yahooery')
    #        link.delete()
    #
    #    @unittest.skip("temporary disabled")
    #    def test_delete_remove_link(self):
    #        link = self.jira.add_remote_link('BULK-3', globalId='python-test:story.of.horse.riding',
    #                                         object={'url': 'http://google.com', 'title': 'googlicious!'},
    #                                         application={'name': 'far too silly', 'type': 'sketch'}, relationship='mousebending')
    #        _id = link.id
    #        link.delete()
    #        self.assertRaises(JIRAError, self.jira.remote_link, 'BULK-3', _id)

    def test_transitioning(self):
        # we check with both issue-as-string or issue-as-object
        transitions = []
        for issue in [self.issue_2, self.jira.issue(self.issue_2)]:
            transitions = self.jira.transitions(issue)
            self.assertTrue(transitions)
            self.assertTrue('id' in transitions[0])
            self.assertTrue('name' in transitions[0])

        self.assertTrue(transitions, msg="Expecting at least one transition")
        # we test getting a single transition
        transition = self.jira.transitions(self.issue_2, transitions[0]['id'])[0]
        self.assertDictEqual(transition, transitions[0])

        # we test the expand of fields
        transition = self.jira.transitions(self.issue_2, transitions[0]['id'],
                                           expand='transitions.fields')[0]
        self.assertTrue('fields' in transition)

        # Testing of transition with field assignment is disabled now because default workflows do not have it.

        # self.jira.transition_issue(issue, transitions[0]['id'], assignee={'name': self.test_manager.CI_JIRA_ADMIN})
        # issue = self.jira.issue(issue.key)
        # self.assertEqual(issue.fields.assignee.name, self.test_manager.CI_JIRA_ADMIN)
        #
        # fields = {
        #     'assignee': {
        #         'name': self.test_manager.CI_JIRA_USER
        #     }
        # }
        # transitions = self.jira.transitions(issue.key)
        # self.assertTrue(transitions)  # any issue should have at least one transition available to it
        # transition_id = transitions[0]['id']
        #
        # self.jira.transition_issue(issue.key, transition_id, fields=fields)
        # issue = self.jira.issue(issue.key)
        # self.assertEqual(issue.fields.assignee.name, self.test_manager.CI_JIRA_USER)
        # self.assertEqual(issue.fields.status.id, transition_id)

    def test_votes(self):
        self.jira_normal.remove_vote(self.issue_1)
        # not checking the result on this
        votes = self.jira.votes(self.issue_1)
        self.assertEqual(votes.votes, 0)

        self.jira_normal.add_vote(self.issue_1)
        new_votes = self.jira.votes(self.issue_1)
        assert votes.votes + 1 == new_votes.votes

        self.jira_normal.remove_vote(self.issue_1)
        new_votes = self.jira.votes(self.issue_1)
        assert votes.votes == new_votes.votes

    def test_votes_with_issue_obj(self):
        issue = self.jira_normal.issue(self.issue_1)
        self.jira_normal.remove_vote(issue)
        # not checking the result on this
        votes = self.jira.votes(issue)
        self.assertEqual(votes.votes, 0)

        self.jira_normal.add_vote(issue)
        new_votes = self.jira.votes(issue)
        assert votes.votes + 1 == new_votes.votes

        self.jira_normal.remove_vote(issue)
        new_votes = self.jira.votes(issue)
        assert votes.votes == new_votes.votes

    def test_add_remove_watcher(self):

        # removing it in case it exists, so we know its state
        self.jira.remove_watcher(self.issue_1, self.test_manager.CI_JIRA_USER)
        init_watchers = self.jira.watchers(self.issue_1).watchCount

        # adding a new watcher
        self.jira.add_watcher(self.issue_1, self.test_manager.CI_JIRA_USER)
        self.assertEqual(self.jira.watchers(self.issue_1).watchCount,
                         init_watchers + 1)

        # now we verify that remove does indeed remove watchers
        self.jira.remove_watcher(self.issue_1, self.test_manager.CI_JIRA_USER)
        new_watchers = self.jira.watchers(self.issue_1).watchCount
        self.assertEqual(init_watchers, new_watchers)

    @not_on_custom_jira_instance
    def test_agile(self):
        uniq = rndstr()
        board_name = 'board-' + uniq
        sprint_name = 'sprint-' + uniq

        b = self.jira.create_board(board_name, self.project_a)
        assert isinstance(b.id, integer_types)

        s = self.jira.create_sprint(sprint_name, b.id)
        assert isinstance(s.id, integer_types)
        assert s.name == sprint_name
        assert s.state == 'FUTURE'

        self.jira.add_issues_to_sprint(s.id, [self.issue_1])

        sprint_field_name = "Sprint"
        sprint_field_id = [f['schema']['customId'] for f in self.jira.fields()
                           if f['name'] == sprint_field_name][0]
        sprint_customfield = "customfield_" + str(sprint_field_id)

        updated_issue_1 = self.jira.issue(self.issue_1)
        serialised_sprint = getattr(updated_issue_1.fields, sprint_customfield)[0]

        # Too hard to serialise the sprint object. Performing simple regex match instead.
        assert re.search('\[id=' + str(s.id) + ',', serialised_sprint)

        # self.jira.add_issues_to_sprint(s.id, self.issue_2)

        # self.jira.rank(self.issue_2, self.issue_1)

        s.delete()

        b.delete()
        # self.jira.delete_board(b.id)

    def test_worklogs(self):
        worklog = self.jira.add_worklog(self.issue_1, '2h')
        worklogs = self.jira.worklogs(self.issue_1)
        self.assertEqual(len(worklogs), 1)
        worklog.delete()

    def test_worklogs_with_issue_obj(self):
        issue = self.jira.issue(self.issue_1)
        worklog = self.jira.add_worklog(issue, '2h')
        worklogs = self.jira.worklogs(issue)
        self.assertEqual(len(worklogs), 1)
        worklog.delete()

    def test_worklog(self):
        worklog = self.jira.add_worklog(self.issue_1, '1d 2h')
        new_worklog = self.jira.worklog(self.issue_1, str(worklog))
        self.assertEqual(new_worklog.author.name, self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(new_worklog.timeSpent, '1d 2h')
        worklog.delete()

    def test_worklog_with_issue_obj(self):
        issue = self.jira.issue(self.issue_1)
        worklog = self.jira.add_worklog(issue, '1d 2h')
        new_worklog = self.jira.worklog(issue, str(worklog))
        self.assertEqual(new_worklog.author.name, self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(new_worklog.timeSpent, '1d 2h')
        worklog.delete()

    def test_add_worklog(self):
        worklog_count = len(self.jira.worklogs(self.issue_2))
        worklog = self.jira.add_worklog(self.issue_2, '2h')
        self.assertIsNotNone(worklog)
        self.assertEqual(len(self.jira.worklogs(self.issue_2)), worklog_count + 1)
        worklog.delete()

    def test_add_worklog_with_issue_obj(self):
        issue = self.jira.issue(self.issue_2)
        worklog_count = len(self.jira.worklogs(issue))
        worklog = self.jira.add_worklog(issue, '2h')
        self.assertIsNotNone(worklog)
        self.assertEqual(len(self.jira.worklogs(issue)), worklog_count + 1)
        worklog.delete()

    def test_update_and_delete_worklog(self):
        worklog = self.jira.add_worklog(self.issue_3, '3h')
        issue = self.jira.issue(self.issue_3, fields='worklog,timetracking')
        worklog.update(comment='Updated!', timeSpent='2h')
        self.assertEqual(worklog.comment, 'Updated!')
        rem_estimate = issue.fields.timetracking.remainingEstimate
        self.assertEqual(worklog.timeSpent, '2h')
        issue = self.jira.issue(self.issue_3, fields='worklog,timetracking')
        self.assertEqual(issue.fields.timetracking.remainingEstimate, "1h")
        worklog.delete()
        issue = self.jira.issue(self.issue_3, fields='worklog,timetracking')
        self.assertEqual(issue.fields.timetracking.remainingEstimate, "3h")

class IssueLinkTests(unittest.TestCase):

    def setUp(self):
        self.manager = JiraTestManager()
        self.link_types = self.manager.jira_admin.issue_link_types()

    def test_issue_link(self):
        self.link = self.manager.jira_admin.issue_link_type(self.link_types[0].id)
        link = self.link  # Duplicate outward
        self.assertEqual(link.id, self.link_types[0].id)

    def test_create_issue_link(self):
        self.manager.jira_admin.create_issue_link(self.link_types[0].outward,
                                                  JiraTestManager().project_b_issue1,
                                                  JiraTestManager().project_b_issue2)

    def test_create_issue_link_with_issue_objs(self):
        inwardissue = self.manager.jira_admin.issue(
            JiraTestManager().project_b_issue1)
        self.assertIsNotNone(inwardissue)
        outwardissue = self.manager.jira_admin.issue(
            JiraTestManager().project_b_issue2)
        self.assertIsNotNone(outwardissue)
        self.manager.jira_admin.create_issue_link(self.link_types[0].outward,
                                                  inwardissue, outwardissue)

        # @unittest.skip("Creating an issue link doesn't return its ID, so can't easily test delete")
        # def test_delete_issue_link(self):
        #    pass

    def test_issue_link_type(self):
        link_type = self.manager.jira_admin.issue_link_type(self.link_types[0].id)
        self.assertEqual(link_type.id, self.link_types[0].id)
        self.assertEqual(link_type.name, self.link_types[0].name)

class MyPermissionsTests(unittest.TestCase):

    def setUp(self):
        self.test_manager = JiraTestManager()
        self.jira = JiraTestManager().jira_normal
        self.issue_1 = self.test_manager.project_b_issue1

    def test_my_permissions(self):
        perms = self.jira.my_permissions()
        self.assertGreaterEqual(len(perms['permissions']), 40)

    def test_my_permissions_by_project(self):
        perms = self.jira.my_permissions(projectKey=self.test_manager.project_a)
        self.assertGreaterEqual(len(perms['permissions']), 10)
        perms = self.jira.my_permissions(projectId=self.test_manager.project_a_id)
        self.assertGreaterEqual(len(perms['permissions']), 10)

    @unittest.skip("broken")
    def test_my_permissions_by_issue(self):
        perms = self.jira.my_permissions(issueKey='ZTRAVISDEB-7')
        self.assertGreaterEqual(len(perms['permissions']), 10)
        perms = self.jira.my_permissions(issueId='11021')
        self.assertGreaterEqual(len(perms['permissions']), 10)

class PrioritiesTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_priorities(self):
        priorities = self.jira.priorities()
        self.assertEqual(len(priorities), 5)

    @not_on_custom_jira_instance
    def test_priority(self):
        priority = self.jira.priority('2')
        self.assertEqual(priority.id, '2')
        self.assertEqual(priority.name, 'Critical')

class ProjectTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.project_b = JiraTestManager().project_b
        self.test_manager = JiraTestManager()

    def test_projects(self):
        projects = self.jira.projects()
        self.assertGreaterEqual(len(projects), 2)

    def test_project(self):
        project = self.jira.project(self.project_b)
        self.assertEqual(project.key, self.project_b)

    # I have no idea what avatars['custom'] is and I get different results every time
    #    def test_project_avatars(self):
    #        avatars = self.jira.project_avatars(self.project_b)
    #        self.assertEqual(len(avatars['custom']), 3)
    #        self.assertEqual(len(avatars['system']), 16)
    #
    #    def test_project_avatars_with_project_obj(self):
    #        project = self.jira.project(self.project_b)
    #        avatars = self.jira.project_avatars(project)
    #        self.assertEqual(len(avatars['custom']), 3)
    #        self.assertEqual(len(avatars['system']), 16)

    #    def test_create_project_avatar(self):
    # Tests the end-to-end project avatar creation process: upload as temporary, confirm after cropping,
    # and selection.
    #        project = self.jira.project(self.project_b)
    #        size = os.path.getsize(TEST_ICON_PATH)
    #        filename = os.path.basename(TEST_ICON_PATH)
    #        with open(TEST_ICON_PATH, "rb") as icon:
    #            props = self.jira.create_temp_project_avatar(project, filename, size, icon.read())
    #        self.assertIn('cropperOffsetX', props)
    #        self.assertIn('cropperOffsetY', props)
    #        self.assertIn('cropperWidth', props)
    #        self.assertTrue(props['needsCropping'])
    #
    #        props['needsCropping'] = False
    #        avatar_props = self.jira.confirm_project_avatar(project, props)
    #        self.assertIn('id', avatar_props)
    #
    #        self.jira.set_project_avatar(self.project_b, avatar_props['id'])
    #
    #    def test_delete_project_avatar(self):
    #        size = os.path.getsize(TEST_ICON_PATH)
    #        filename = os.path.basename(TEST_ICON_PATH)
    #        with open(TEST_ICON_PATH, "rb") as icon:
    #            props = self.jira.create_temp_project_avatar(self.project_b, filename, size, icon.read(), auto_confirm=True)
    #        self.jira.delete_project_avatar(self.project_b, props['id'])
    #
    #    def test_delete_project_avatar_with_project_obj(self):
    #        project = self.jira.project(self.project_b)
    #        size = os.path.getsize(TEST_ICON_PATH)
    #        filename = os.path.basename(TEST_ICON_PATH)
    #        with open(TEST_ICON_PATH, "rb") as icon:
    #            props = self.jira.create_temp_project_avatar(project, filename, size, icon.read(), auto_confirm=True)
    #        self.jira.delete_project_avatar(project, props['id'])

    def test_set_project_avatar(self):
        def find_selected_avatar(avatars):
            for avatar in avatars['system']:
                if avatar['isSelected']:
                    return avatar
            else:
                raise Exception

        self.jira.set_project_avatar(self.project_b, '10001')
        avatars = self.jira.project_avatars(self.project_b)
        self.assertEqual(find_selected_avatar(avatars)['id'], '10001')

        project = self.jira.project(self.project_b)
        self.jira.set_project_avatar(project, '10208')
        avatars = self.jira.project_avatars(project)
        self.assertEqual(find_selected_avatar(avatars)['id'], '10208')

    def test_project_components(self):
        proj = self.jira.project(self.project_b)
        name = "component-%s from project %s" % (proj, rndstr())
        component = self.jira.create_component(name,
                                               proj, description='test!!', assigneeType='COMPONENT_LEAD',
                                               isAssigneeTypeValid=False)
        components = self.jira.project_components(self.project_b)
        self.assertGreaterEqual(len(components), 1)
        sample = find_by_id(components, component.id)
        self.assertEqual(sample.id, component.id)
        self.assertEqual(sample.name, name)
        component.delete()

    def test_project_versions(self):
        name = "version-%s" % rndstr()
        version = self.jira.create_version(name,
                                           self.project_b, "will be deleted soon")
        versions = self.jira.project_versions(self.project_b)
        self.assertGreaterEqual(len(versions), 1)
        test = find_by_id(versions, version.id)
        self.assertEqual(test.id, version.id)
        self.assertEqual(test.name, name)

        i = self.jira.issue(JiraTestManager().project_b_issue1)
        i.update(fields={
            'versions': [{'id': version.id}],
            'fixVersions': [{'id': version.id}]
        })
        version.delete()

    def test_project_versions_with_project_obj(self):
        name = "version-%s" % rndstr()
        version = self.jira.create_version(name,
                                           self.project_b, "will be deleted soon")
        project = self.jira.project(self.project_b)
        versions = self.jira.project_versions(project)
        self.assertGreaterEqual(len(versions), 1)
        test = find_by_id(versions, version.id)
        self.assertEqual(test.id, version.id)
        self.assertEqual(test.name, name)
        version.delete()

    @unittest.skip("temporary disabled because roles() return a dictionary of role_name:role_url and we have no call to convert it to proper Role()")
    def test_project_roles(self):
        project = self.jira.project(self.project_b)
        role_name = 'Developers'
        dev = None
        for roles in [self.jira.project_roles(self.project_b), self.jira.project_roles(project)]:
            self.assertGreaterEqual(len(roles), 5)
            self.assertIn('Users', roles)
            self.assertIn(role_name, roles)
            dev = roles[role_name]
        self.assertTrue(dev)
        role = self.jira.project_role(self.project_b, dev.id)
        self.assertEqual(role.id, dev.id)
        self.assertEqual(role.name, dev.name)
        user = self.test_manager.jira_admin
        self.assertNotIn(user, role.actors)
        role.update(users=user, groups=['jira-developers', 'jira-users'])
        role = self.jira.project_role(self.project_b, dev.id)
        self.assertIn(user, role.actors)

@not_on_custom_jira_instance
class ResolutionTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_resolutions(self):
        resolutions = self.jira.resolutions()
        self.assertGreaterEqual(len(resolutions), 1)

    def test_resolution(self):
        resolution = self.jira.resolution('2')
        self.assertEqual(resolution.id, '2')
        self.assertEqual(resolution.name, 'Won\'t Fix')

class SearchTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.project_b = JiraTestManager().project_b
        self.test_manager = JiraTestManager()
        self.issue = self.test_manager.project_b_issue1

    def test_search_issues(self):
        issues = self.jira.search_issues('project=%s' % self.project_b)
        self.assertLessEqual(len(issues), 50)  # default maxResults
        for issue in issues:
            self.assertTrue(issue.key.startswith(self.project_b))

    def test_search_issues_maxresults(self):
        issues = self.jira.search_issues('project=%s' % self.project_b,
                                         maxResults=10)
        self.assertLessEqual(len(issues), 10)

    def test_search_issues_startat(self):
        issues = self.jira.search_issues('project=%s' % self.project_b,
                                         startAt=5770, maxResults=500)
        self.assertLessEqual(len(issues), 500)

    def test_search_issues_field_limiting(self):
        issues = self.jira.search_issues('key=%s' % self.issue,
                                         fields='summary,comment')
        self.assertTrue(hasattr(issues[0].fields, 'summary'))
        self.assertTrue(hasattr(issues[0].fields, 'comment'))
        self.assertFalse(hasattr(issues[0].fields, 'reporter'))
        self.assertFalse(hasattr(issues[0].fields, 'progress'))

    def test_search_issues_expandos(self):
        issues = self.jira.search_issues('key=%s' % self.issue,
                                         expand='changelog')
        # self.assertTrue(hasattr(issues[0], 'names'))
        self.assertEqual(len(issues), 1)
        self.assertFalse(hasattr(issues[0], 'editmeta'))
        self.assertTrue(hasattr(issues[0], 'changelog'))
        self.assertEqual(issues[0].key, self.issue)

@unittest.skip("Skipped due to https://jira.atlassian.com/browse/JRA-59619")
class SecurityLevelTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_security_level(self):
        # This is hardcoded due to Atlassian bug: https://jira.atlassian.com/browse/JRA-59619
        sec_level = self.jira.security_level('10000')
        self.assertEqual(sec_level.id, '10000')

class ServerInfoTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_server_info(self):
        server_info = self.jira.server_info()
        self.assertIn('baseUrl', server_info)
        self.assertIn('version', server_info)

class StatusTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_statuses(self):
        found = False
        for status in self.jira.statuses():
            if status.id == '1' and status.name == 'Open':
                found = True
                break
        self.assertTrue(found, "Status Open with id=1 not found.")

    def test_status(self):
        status = self.jira.status('1')
        self.assertEqual(status.id, '1')
        self.assertEqual(status.name, 'Open')

class UserTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.project_a = JiraTestManager().project_a
        self.project_b = JiraTestManager().project_b
        self.test_manager = JiraTestManager()
        self.issue = self.test_manager.project_b_issue3

    def test_user(self):
        user = self.jira.user(self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(user.name, self.test_manager.CI_JIRA_ADMIN)
        self.assertRegex(user.emailAddress, '.*@example.com')

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_projects(self):
        users = self.jira.search_assignable_users_for_projects(self.test_manager.CI_JIRA_ADMIN,
                                                               '%s,%s' % (self.project_a, self.project_b))
        self.assertGreaterEqual(len(users), 1)
        usernames = map(lambda user: user.name, users)
        self.assertIn(self.test_manager.CI_JIRA_ADMIN, usernames)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_projects_maxresults(self):
        users = self.jira.search_assignable_users_for_projects(self.test_manager.CI_JIRA_ADMIN,
                                                               '%s,%s' % (self.project_a, self.project_b), maxResults=1)
        self.assertLessEqual(len(users), 1)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_projects_startat(self):
        users = self.jira.search_assignable_users_for_projects(self.test_manager.CI_JIRA_ADMIN,
                                                               '%s,%s' % (self.project_a, self.project_b), startAt=1)
        self.assertGreaterEqual(len(users), 0)

    @not_on_custom_jira_instance
    def test_search_assignable_users_for_issues_by_project(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_ADMIN,
                                                             project=self.project_b)
        self.assertEqual(len(users), 1)
        usernames = map(lambda user: user.name, users)
        self.assertIn(self.test_manager.CI_JIRA_ADMIN, usernames)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_issues_by_project_maxresults(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_USER,
                                                             project=self.project_b, maxResults=1)
        self.assertLessEqual(len(users), 1)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_issues_by_project_startat(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_USER,
                                                             project=self.project_a, startAt=1)
        self.assertGreaterEqual(len(users), 0)

    @not_on_custom_jira_instance
    def test_search_assignable_users_for_issues_by_issue(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_ADMIN,
                                                             issueKey=self.issue)
        self.assertEqual(len(users), 1)
        usernames = map(lambda user: user.name, users)
        self.assertIn(self.test_manager.CI_JIRA_ADMIN, usernames)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_issues_by_issue_maxresults(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_ADMIN,
                                                             issueKey=self.issue, maxResults=2)
        self.assertLessEqual(len(users), 2)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_assignable_users_for_issues_by_issue_startat(self):
        users = self.jira.search_assignable_users_for_issues(self.test_manager.CI_JIRA_ADMIN,
                                                             issueKey=self.issue, startAt=2)
        self.assertGreaterEqual(len(users), 0)

    def test_user_avatars(self):
        # Tests the end-to-end user avatar creation process: upload as temporary, confirm after cropping,
        # and selection.
        size = os.path.getsize(TEST_ICON_PATH)
        filename = os.path.basename(TEST_ICON_PATH)
        with open(TEST_ICON_PATH, "rb") as icon:
            props = self.jira.create_temp_user_avatar(JiraTestManager().CI_JIRA_ADMIN, TEST_ICON_PATH,
                                                      size, icon.read())
        self.assertIn('cropperOffsetX', props)
        self.assertIn('cropperOffsetY', props)
        self.assertIn('cropperWidth', props)
        self.assertTrue(props['needsCropping'])

        props['needsCropping'] = False
        avatar_props = self.jira.confirm_user_avatar(JiraTestManager().CI_JIRA_ADMIN, props)
        self.assertIn('id', avatar_props)
        self.assertEqual(avatar_props['owner'], JiraTestManager().CI_JIRA_ADMIN)

        self.jira.set_user_avatar(JiraTestManager().CI_JIRA_ADMIN, avatar_props['id'])

        avatars = self.jira.user_avatars(self.test_manager.CI_JIRA_ADMIN)
        self.assertGreaterEqual(len(avatars['system']), 20)  # observed values between 20-24 so far
        self.assertGreaterEqual(len(avatars['custom']), 1)

    @unittest.skip("broken: set avatar returns 400")
    def test_set_user_avatar(self):
        def find_selected_avatar(avatars):
            for avatar in avatars['system']:
                if avatar['isSelected']:
                    return avatar
            # else:
            #     raise Exception as e
            #     print(e)

        avatars = self.jira.user_avatars(self.test_manager.CI_JIRA_ADMIN)

        self.jira.set_user_avatar(self.test_manager.CI_JIRA_ADMIN, avatars['system'][0])
        avatars = self.jira.user_avatars(self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(find_selected_avatar(avatars)['id'], avatars['system'][0])

        self.jira.set_user_avatar(self.test_manager.CI_JIRA_ADMIN, avatars['system'][1])
        avatars = self.jira.user_avatars(self.test_manager.CI_JIRA_ADMIN)
        self.assertEqual(find_selected_avatar(avatars)['id'], avatars['system'][1])

    @unittest.skip("disable until I have permissions to write/modify")
    # WRONG
    def test_delete_user_avatar(self):
        size = os.path.getsize(TEST_ICON_PATH)
        filename = os.path.basename(TEST_ICON_PATH)
        with open(TEST_ICON_PATH, "rb") as icon:
            props = self.jira.create_temp_user_avatar(self.test_manager.CI_JIRA_ADMIN, filename,
                                                      size, icon.read())
        # print(props)
        self.jira.delete_user_avatar(self.test_manager.CI_JIRA_ADMIN, props['id'])

    def test_search_users(self):
        users = self.jira.search_users(self.test_manager.CI_JIRA_USER)
        self.assertGreaterEqual(len(users), 1)
        usernames = map(lambda user: user.name, users)
        self.assertIn(self.test_manager.CI_JIRA_USER, usernames)

    def test_search_users_maxresults(self):
        users = self.jira.search_users(self.test_manager.CI_JIRA_USER, maxResults=1)
        self.assertGreaterEqual(len(users), 1)

    def test_search_allowed_users_for_issue_by_project(self):
        users = self.jira.search_allowed_users_for_issue(self.test_manager.CI_JIRA_USER,
                                                         projectKey=self.project_a)
        self.assertGreaterEqual(len(users), 1)

    @not_on_custom_jira_instance
    def test_search_allowed_users_for_issue_by_issue(self):
        users = self.jira.search_allowed_users_for_issue('a',
                                                         issueKey=self.issue)
        self.assertGreaterEqual(len(users), 1)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_allowed_users_for_issue_maxresults(self):
        users = self.jira.search_allowed_users_for_issue('a',
                                                         projectKey=self.project_b, maxResults=2)
        self.assertLessEqual(len(users), 2)

    @pytest.mark.xfail(reason='query returns empty list')
    def test_search_allowed_users_for_issue_startat(self):
        users = self.jira.search_allowed_users_for_issue('c',
                                                         projectKey=self.project_b, startAt=1)
        self.assertGreaterEqual(len(users), 0)

    def test_add_users_to_set(self):
        users_set = set(
            [self.jira.user(self.test_manager.CI_JIRA_ADMIN), self.jira.user(self.test_manager.CI_JIRA_ADMIN)])
        self.assertEqual(len(users_set), 1)

class VersionTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.project_b = JiraTestManager().project_b

    def test_create_version(self):
        version = self.jira.create_version('new version 1', self.project_b,
                                           releaseDate='2015-03-11', description='test version!')
        self.assertEqual(version.name, 'new version 1')
        self.assertEqual(version.description, 'test version!')
        self.assertEqual(version.releaseDate, '2015-03-11')
        version.delete()

    def test_create_version_with_project_obj(self):
        project = self.jira.project(self.project_b)
        version = self.jira.create_version('new version 1', project,
                                           releaseDate='2015-03-11', description='test version!')
        self.assertEqual(version.name, 'new version 1')
        self.assertEqual(version.description, 'test version!')
        self.assertEqual(version.releaseDate, '2015-03-11')
        version.delete()

    def test_update(self):

        version = self.jira.create_version('new updated version 1',
                                           self.project_b, releaseDate='2015-03-11',
                                           description='new to be updated!')
        version.update(name='new updated version name 1',
                       description='new updated!')
        self.assertEqual(version.name, 'new updated version name 1')
        self.assertEqual(version.description, 'new updated!')

        v = self.jira.version(version.id)
        self.assertEqual(v, version)
        self.assertEqual(v.id, version.id)

        version.delete()

    def test_delete(self):
        version = self.jira.create_version('To be deleted', self.project_b,
                                           releaseDate='2015-03-11',
                                           description='not long for this world')
        myid = version.id
        version.delete()
        self.assertRaises(JIRAError, self.jira.version, myid)

    def test_version_expandos(self):
        pass

class OtherTests(unittest.TestCase):

    def test_session_invalid_login(self):
        try:
            JIRA('https://support.atlassian.com',
                 basic_auth=("xxx", "xxx"),
                 validate=True,
                 logging=False)
        except Exception as e:
            self.assertIsInstance(e, JIRAError)
            assert e.status_code == 401
            str(JIRAError)  # to see that this does not raise an exception
            return
        assert False

class SessionTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_session(self):
        user = self.jira.session()
        self.assertIsNotNone(user.raw['session'])

    def test_session_with_no_logged_in_user_raises(self):
        anon_jira = JIRA('https://support.atlassian.com', logging=False)
        self.assertRaises(JIRAError, anon_jira.session)

    #@pytest.mark.skipif(platform.python_version() < '3', reason='Does not work with Python 2')
    #@not_on_custom_jira_instance  # takes way too long
    def test_session_server_offline(self):
        try:
            JIRA('https://127.0.0.1:1', logging=False, max_retries=0)
        except Exception as e:
            self.assertIn(type(e), (JIRAError, requests.exceptions.ConnectionError, AttributeError), e)
            return
        self.assertTrue(False, "Instantiation of invalid JIRA instance succeeded.")

class WebsudoTests(unittest.TestCase):

    def setUp(self):
        self.jira = JiraTestManager().jira_admin

    def test_kill_websudo(self):
        self.jira.kill_websudo()

    # def test_kill_websudo_without_login_raises(self):
    #    self.assertRaises(ConnectionError, JIRA)

class UserAdministrationTests(unittest.TestCase):
    jira = None

    def setUp(self):
        self.jira = JiraTestManager().jira_admin
        self.test_username = "test_%s" % JiraTestManager().project_a
        self.test_email = "%s@example.com" % self.test_username
        self.test_password = rndpassword()
        self.test_groupname = 'testGroupFor_%s' % JiraTestManager().project_a

    @pytest.mark.xfail(reason='User is present in JIRA, but cannot be found via REST API.')
    def test_add_user(self):

        try:
            self.jira.delete_user(self.test_username)
        except JIRAError as e:
            pass

        result = self.jira.add_user(
            self.test_username, self.test_email, password=self.test_password)
        assert result, True

        x = self.jira.search_users(self.test_username)[0]
        assert isinstance(x, jira.User)

        x = self.jira.delete_user(self.test_username)
        assert x, True

    @pytest.mark.xfail(reason='query returns empty list')
    def test_delete_user(self):
        try:
            # Make sure user exists before attempting test to delete.
            self.jira.add_user(
                self.test_username, self.test_email, password=self.test_password)
        except JIRAError:
            pass

        result = self.jira.delete_user(self.test_username)
        assert result, True

        x = self.jira.search_users(self.test_username)
        self.assertEqual(
            len(x), 0, "Found test user when it should have been deleted. Test Fails.")

    def test_add_group(self):
        try:
            self.jira.remove_group(self.test_groupname)
        except JIRAError:
            pass

        result = self.jira.add_group(self.test_groupname)
        assert result, True

        x = self.jira.groups(query=self.test_groupname)
        self.assertEqual(self.test_groupname, x[0], "Did not find expected group after trying to add"
                                                    " it. Test Fails.")
        self.jira.remove_group(self.test_groupname)

    def test_remove_group(self):
        try:
            self.jira.add_group(self.test_groupname)
        except JIRAError:
            pass

        result = self.jira.remove_group(self.test_groupname)
        assert result, True

        x = self.jira.groups(query=self.test_groupname)
        self.assertEqual(len(
            x), 0, 'Found group with name when it should have been deleted. Test Fails.')

    @not_on_custom_jira_instance
    def test_add_user_to_group(self):
        try:
            self.jira.add_user(
                self.test_username, self.test_email, password=self.test_password)
            self.jira.add_group(self.test_groupname)
            # Just in case user is already there.
            self.jira.remove_user_from_group(
                self.test_username, self.test_groupname)
        except JIRAError:
            pass

        result = self.jira.add_user_to_group(
            self.test_username, self.test_groupname)
        assert result, True

        x = self.jira.group_members(self.test_groupname)
        self.assertIn(self.test_username, x.keys(),
                      'Username not returned in group member list. Test Fails.')
        self.assertIn('email', x[self.test_username])
        self.assertIn('fullname', x[self.test_username])
        self.assertIn('active', x[self.test_username])
        self.jira.remove_group(self.test_groupname)
        self.jira.delete_user(self.test_username)

    def test_remove_user_from_group(self):
        try:
            self.jira.add_user(
                self.test_username, self.test_email, password=self.test_password)
            self.jira.add_group(self.test_groupname)
            self.jira.add_user_to_group(
                self.test_username, self.test_groupname)
        except JIRAError:
            pass

        result = self.jira.remove_user_from_group(
            self.test_username, self.test_groupname)
        assert result, True

        x = self.jira.group_members(self.test_groupname)
        self.assertNotIn(self.test_username, x.keys(), 'Username found in group when it should have been removed. '
                                                       'Test Fails.')

        self.jira.remove_group(self.test_groupname)
        self.jira.delete_user(self.test_username)

if __name__ == '__main__':

    # when running tests we expect various errors and we don't want to display them by default
    logging.getLogger("requests").setLevel(logging.FATAL)
    logging.getLogger("urllib3").setLevel(logging.FATAL)
    logging.getLogger("jira").setLevel(logging.FATAL)

    # j = JIRA("https://issues.citrite.net")
    # print(j.session())

    dirname = "test-reports-%s%s" % (sys.version_info[0], sys.version_info[1])
    unittest.main()
    # pass

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

<title>Internationales Freundschafts YL-Treffen OE88YL</title>

<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="robots" content="index, follow">
<meta name="revisit-after" content="7 days">

<link rel="apple-touch-icon" href="/export/sites/oe6/favicon.png" />
<link rel="icon" href="/export/sites/oe6/favicon.png" type="image/png" />

<link rel="stylesheet" href="/export/system/modules/at.oevsv.apollo.extensions/resources/css/style-oevsv.min.css" />

<link rel="alternate" type="application/rss+xml" href="/adl619/rss-events.xml" title="Veranstaltungen & Termine">
<link rel="alternate" type="application/rss+xml" href="/adl619/rss-news.xml" title="Aktuelles">
<link rel="alternate" type="application/rss+xml" href="/adl-vorlage/rss-events.xml" title="Veranstaltungen & Termine">
<link rel="alternate" type="application/rss+xml" href="/adl-vorlage/rss-news.xml" title="Aktuelles">
<link rel="alternate" type="application/rss+xml" href="/adl601/rss-events.xml" title="Veranstaltungen & Termine">
<link rel="alternate" type="application/rss+xml" href="/adl601/rss-news.xml" title="Aktuelles">
<link rel="alternate" type="application/rss+xml" href="/rss-events.xml" title="Veranstaltungen & Termine">
<link rel="alternate" type="application/rss+xml" href="/rss-news.xml" title="Aktuelles">
<link rel="alternate" type="application/rss+xml" href="/adl602/rss-events.xml" title="Veranstaltungen & Termine">
<link rel="alternate" type="application/rss+xml" href="/adl602/rss-news.xml" title="Aktuelles">

                                ÖVSV - LANDESVERBÄNDE

OE1 Wien

OE2 Salzburg

OE3 Niederösterreich

OE4 Burgenland

OE5 Oberösterreich

OE6 Steiermark

OE7 Tirol

OE8 Kärnten

OE9 Vorarlberg

AMRS

Dachverband

                                Login

                <button type="button" class="navbar-toggle" data-toggle="collapse"
					data-target=".navbar-responsive-collapse">
					Toggle navigation
				</button>

		Ortsstellen, Clubabende

		Übersicht Clubabende

		ADL 601 - Graz

		ADL 602 - Mürztal

		ADL 603 - Liezen

		ADL 604 - Hartberg

		ADL 605 - Weiz

		Mitglieder

		Clubabend

		ADL 606 - Leoben

		ADL 607 - Murau

		ADL 608 - Fürstenfeld

		ADL 609 - Judenburg

		ADL 610 - Feldbach

		ADL 611 - Steirisches Hügelland

		ADL 612 - Deutschlandsberg

		ADL 613 - Leibnitz

		ADL 615 - Club Telescout

		ADL 617 - Kremstal

		ADL 619 - Graz Umgebung

		ADL 620 - Kainachtal

		ADL 621 - Oberes Ennstal

		ADL 622 - Bruck an der Mur

		ADL 623 - Graz Vulkanland realraum

		Clubabend

		Mitglieder

		Geschichte

		Aktivitäten

		ARDF

		Ausbildung

		CW-Schule Graz

		Aktivitäten

		Unterlagen

		Literatur

		Präsentationen

		Software

		Digitaler Sprechfunk

		DMR

		DSTAR

		C4FM

		Fieldday Dobl

		Dobl 2019

		Dobl 2018

		Dobl 2017

		Dobl 2016

		Dobl 2015

		Dobl 2014

		Dobl 2013

		Dobl 2012

		Dobl 1988

		Not- und Katastrophenfunk

		Outdoor

		QSL Vermittlung

		Web-Auftritt

		Outdoor

		Verein

		Landesverband

		Vereinsorgane

		Mitglied werden

		Ehrungen

		Ehrenmitglieder

		in Memoriam

		2019

		2018

		2017

		2016

		2015

		2014

		2013

		2012

		2011

		2010

		2009

		Home

		<form class="form-inline" name="searchFormHeader" action="/suche/" method="post">

				<input type="text" name="q" class="form-control" placeholder="Search" id="searchWidgetAutoCompleteHeader" />

					<button class="btn-u" type="button" onclick="this.form.submit(); return false;">Go</button>

		</form>

Internationales Freundschafts YL-Treffen OE88YL

 05.07.19 00:00 - 07.07.19 00:00

 Download Event

  Öffentlichkeitsarbeit
										On the Air
										Treffen
										Alle Verbände
										AMRS
										OE3
										ÖVSV Dachverband

In vielen Ländern gibt es ja schon YL Treffen. Daher versuchen wir, das YL-Team der AMRS-Waldviertel, auch in OE eines zu organisieren.
 Also Mädels, packt Eure OM's zusammen und macht ein paar Tage Urlaub inklusive Funkbetrieb im schönen Waldviertel. Wir würden uns sehr auf ein Wiedersehen bzw. Kennenlernen in einer netten und gemütlichen Runde freuen!!!

Veranstaltungszeitraum: Freitag 05.Juli 2019 bis Sonntag 07.Juli 2019
 Veranstaltungsort: Freizeitzentrum am Stadtsee in 3804 Allentsteig

Allgemeines:

 Das Treffen findet vom 05.07.2019 bis 07.07.2019 im Freizeitzentrum in Allentsteig statt. Allentsteig liegt in Niederösterreich in mitten des schönen Waldviertels. Der Stadtsee wird auch als Badeteich genutzt und liegt in ruhiger Lage am Stadtrand.

 Beim Freizeitzentrum gibt es eine gemütliche Blockhütte mit einem Grillplatz, Duschen, Toiletten und einer begrenzten Anzahl an Campingstellplätzen. Quartiere gibt es in und um Allentsteig. Außerdem ist genug Platz für unsere Funkaktivitäten, wann immer wir Zeit oder Lust dazu haben.

 Programm:

Freitag 5.Juli – Anreisetag:
 Wir erwarten  euch ab 9 Uhr im Freizeitzentrum Allentsteig.
 Zu Mittag gibt es diverse Aufstrichbrote und am Nachmittag wird für Kaffee und Kuchen gesorgt. Am späteren Nachmittag begeben wir uns in die 30km entfernte Burgstadt Heidenreichstein, dort erwartet  uns eine Spezialführung mit Julia OE3YJM durch die Wasserburg.
 Anschließend gemütlicher Ausklang beim Abendessen in der Waldschenke Schreiber in Langschwarza.

Samstag 6.Juli:
 Es geht wieder ab 9 Uhr los.
 Den ganzen Tag Funkbetrieb mit dem Sonderrufzeichen OE88YL.
 Zu Mittag gibt es verschiedenste Würstel aus dem Dreibeinkessel.
 Am Nachmittag können Interessierte mit Heike DL3HD, an einem Bastelprojekt (Solarleuchte aus einem Gurkenglas) teilnehmen. Es sind genügend Lötkolben vorhanden.
 Für Snacks, Getränke, Kaffee und Mehlspeisen ist bestens gesorgt.
 Am Abend verwöhnen wir euch mit Leckereien vom Grill mit anschließender gemütlicher Runde am Lagerfeuer.

Sonntag 7.Juli:
 Heimreise

 Camper bitte schon im Voraus Bescheid geben!
 Strom, WC und Duschen sind vorhanden.
 E-Mail an: marion.stouy@gmx.at

 Leitfunkstation: OE3XRC 145,425 und 145,6375 MHz
 Eine Beschilderung in der Stadt  3804 Allentsteig zum YL-Treffen OE88YL ist vorhanden.

Auf ein Kennenlernen und Wiedersehen, mit vielen Funkamateurinnen aus Österreich und Deutschland und anderen Ländern freut sich das OE88YL-Organisationsteam!

 vy 33+73 DARC YL-Referentin Heike DL3HD mit dem AMRS YL-Team Marion OE3YSC, Julia OE3YJM, Carina OE3YCC und Nadine OE3YHC

Camper bitte schon im Voraus Bescheid geben!
 Strom, WC und Duschen sind vorhanden.
 E-Mail an: marion.stouy@gmx.at

 Leitfunkstation: OE3XRC 145,425 und 145,6375 MHz
 Eine Beschilderung in der Stadt  3804 Allentsteig zum YL-Treffen OE88YL ist vorhanden.

Auf ein Kennenlernen und Wiedersehen, mit vielen Funkamateurinnen aus Österreich und Deutschland und anderen Ländern freut sich das OE88YL-Organisationsteam!

 vy 33+73 DARC YL-Referentin Heike DL3HD mit dem AMRS YL-Team Marion OE3YSC, Julia OE3YJM, Carina OE3YCC und Nadine OE3YHC

Österreichischer Versuchssenderverband
Landesverband Steiermark
Am Sendergrund 15
8143 Dobl-Zwaring

Landesleiter
Ing. Thomas Zurk, OE6TZE
  oe6tze @ oevsv.at

WebSite Angelegenheiten
  webmaster @ oevsv.at

     zum Seitenanfang

     Sitemap

    Impressum - Datenschutzerklärung