<commit_before>"""
========================================
Circular and Elliptical Hough Transforms
========================================

The Hough transform in its simplest form is a `method to detect
straight lines <http://en.wikipedia.org/wiki/Hough_transform>`__
but it can also be used to detect circles or ellipses.

Circle detection
================

In the following example, the Hough transform is used to detect
coin positions and match their edges. We provide a range of
plausible radii. For each radius, two circles are extracted and
we finally keep the five most prominent candidates.
The result shows that coin positions are well-detected.

Algorithm overview
------------------

Given a black circle on a white background, we first guess its
radius (or a range of radii) to construct a new circle.
This circle is applied on each black pixel of the original picture
and the coordinates of this circle are voting in an accumulator.
From this geometrical construction, the original circle center
position receives the highest score.

Note that the accumulator size is built to be larger than the
original picture in order to detect centers outside the frame.
Its size is extended by two times the larger radius.

"""
import numpy as np
import matplotlib.pyplot as plt

from skimage import data, filter, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte

# Load picture and detect edges
image = img_as_ubyte(data.coins()[0:95, 70:370])
edges = filter.canny(image, sigma=3, low_threshold=10, high_threshold=50)

fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))

# Detect two radii
hough_radii = np.arange(15, 30, 2)
hough_res = hough_circle(edges, hough_radii)

centers = []
accums = []
radii = []

for radius, h in zip(hough_radii, hough_res):
    # For each radius, extract two circles
    peaks = peak_local_max(h, num_peaks=2)
    centers.extend(peaks)
    accums.extend(h[peaks[:, 0], peaks[:, 1]])
    radii.extend([radius, radius])

# Draw the most prominent 5 circles
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
    center_x, center_y = centers[idx]
    radius = radii[idx]
    cx, cy = circle_perimeter(center_y, center_x, radius)
    image[cy, cx] = (220, 20, 20)

ax.imshow(image, cmap=plt.cm.gray)
plt.show()

"""
Ellipse detection
=================

In this second example, the aim is to detect the edge of the coffee cup.
Basically, this is a projection of a circle, i.e. an ellipse.
The problem to solve is much more difficult since five parameters have to be determined,
instead of three for circles.

Algorithm overview
------------------

The algorithm takes two different points belonging to the ellipse. It assumes that it is
the main axis. A loop on all the other points determines how much an ellipse passes to
them.

A full description of the algorithm can be found in reference [1].

References
----------
.. [1] Xie, Yonghong, and Qiang Ji. "A new efficient ellipse detection
       method." Pattern Recognition, 2002. Proceedings. 16th International
       Conference on. Vol. 2. IEEE, 2002
"""
import numpy as np
import matplotlib.pyplot as plt

from skimage import data, filter, color
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter

# Load picture, convert to grayscale and detect edges
image_rgb = data.load('coffee.png')[100:240, 110:250]
image_gray = color.rgb2gray(image_rgb)
edges = filter.canny(image_gray, sigma=2.0, low_threshold=0.1, high_threshold=0.6)

# Perform a Hough Transform
accum = hough_ellipse(edges, accuracy=7, threshold=93)
center_y = int(accum[0][1])
center_x = int(accum[0][2])
xradius = int(accum[0][3])
yradius = int(accum[0][4])
angle = accum[0][5]

# Draw the ellipse on the original image
cx, cy = ellipse_perimeter(center_y, center_x, yradius, xradius, orientation=angle)
image_rgb[cy, cx] = (0, 0, 220)
# Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(edges)
edges[cy, cx] = (250, 0, 0)

fig = plt.subplots(figsize=(10, 6))
plt.subplot(1,2,1)
plt.title('Original picture')
plt.imshow(image_rgb)
plt.subplot(1,2,2)
plt.title('Edge (white) and result (red)')
plt.imshow(edges)

plt.show()
<commit_msg>add extra comments<commit_after>"""
========================================
Circular and Elliptical Hough Transforms
========================================

The Hough transform in its simplest form is a `method to detect
straight lines <http://en.wikipedia.org/wiki/Hough_transform>`__
but it can also be used to detect circles or ellipses.
The algorithm assumes that the edge is detected and it is rebust against
noise or missing points.

Circle detection
================

In the following example, the Hough transform is used to detect
coin positions and match their edges. We provide a range of
plausible radii. For each radius, two circles are extracted and
we finally keep the five most prominent candidates.
The result shows that coin positions are well-detected.

Algorithm overview
------------------

Given a black circle on a white background, we first guess its
radius (or a range of radii) to construct a new circle.
This circle is applied on each black pixel of the original picture
and the coordinates of this circle are voting in an accumulator.
From this geometrical construction, the original circle center
position receives the highest score.

Note that the accumulator size is built to be larger than the
original picture in order to detect centers outside the frame.
Its size is extended by two times the larger radius.

"""
import numpy as np
import matplotlib.pyplot as plt

from skimage import data, filter, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte

# Load picture and detect edges
image = img_as_ubyte(data.coins()[0:95, 70:370])
edges = filter.canny(image, sigma=3, low_threshold=10, high_threshold=50)

fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))

# Detect two radii
hough_radii = np.arange(15, 30, 2)
hough_res = hough_circle(edges, hough_radii)

centers = []
accums = []
radii = []

for radius, h in zip(hough_radii, hough_res):
    # For each radius, extract two circles
    peaks = peak_local_max(h, num_peaks=2)
    centers.extend(peaks)
    accums.extend(h[peaks[:, 0], peaks[:, 1]])
    radii.extend([radius, radius])

# Draw the most prominent 5 circles
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
    center_x, center_y = centers[idx]
    radius = radii[idx]
    cx, cy = circle_perimeter(center_y, center_x, radius)
    image[cy, cx] = (220, 20, 20)

ax.imshow(image, cmap=plt.cm.gray)
plt.show()

"""
Ellipse detection
=================

In this second example, the aim is to detect the edge of a coffee cup.
Basically, this is a projection of a circle, i.e. an ellipse.
The problem to solve is much more difficult bacause five parameters have to be determined,
instead of three for circles.

Algorithm overview
------------------

The algorithm takes two different points belonging to the ellipse. It assumes that it is
the main axis. A loop on all the other points determines how much an ellipse passes to
them. A good match corresponds to high accumulator values.

A full description of the algorithm can be found in reference [1].

References
----------
.. [1] Xie, Yonghong, and Qiang Ji. "A new efficient ellipse detection
       method." Pattern Recognition, 2002. Proceedings. 16th International
       Conference on. Vol. 2. IEEE, 2002
"""
import numpy as np
import matplotlib.pyplot as plt

from skimage import data, filter, color
from skimage.transform import hough_ellipse
from skimage.draw import ellipse_perimeter

# Load picture, convert to grayscale and detect edges
image_rgb = data.load('coffee.png')[100:240, 110:250]
image_gray = color.rgb2gray(image_rgb)
edges = filter.canny(image_gray, sigma=2.0, low_threshold=0.1, high_threshold=0.6)

# Perform a Hough Transform
# The accuracy corresponds to the bin size of a major axis.
# The value is chosen in order to get a single high accumulator.
# The threshold eliminates low accumulators
accum = hough_ellipse(edges, accuracy=7, threshold=93)
# Estimated parameters for the ellipse
center_y = int(accum[0][1])
center_x = int(accum[0][2])
xradius = int(accum[0][3])
yradius = int(accum[0][4])
angle = accum[0][5]

# Draw the ellipse on the original image
cx, cy = ellipse_perimeter(center_y, center_x, yradius, xradius, orientation=angle)
image_rgb[cy, cx] = (0, 0, 220)
# Draw the edge (white) and the resulting ellipse (red)
edges = color.gray2rgb(edges)
edges[cy, cx] = (250, 0, 0)

fig = plt.subplots(figsize=(10, 6))
plt.subplot(1,2,1)
plt.title('Original picture')
plt.imshow(image_rgb)
plt.subplot(1,2,2)
plt.title('Edge (white) and result (red)')
plt.imshow(edges)

plt.show()
<|endoftext|>


<commit_before># highway=path, with route national (Pacific Crest Trail) at zoom 9
# https://www.openstreetmap.org/way/236361475
# https://www.openstreetmap.org/relation/1225378
assert_has_feature(
    9, 86, 197, 'roads',
    { 'kind': 'path', 'walking_network': 'nwn'})

# highway=path, with route regional (Merced Pass Trail) at zoom 10
# https://www.openstreetmap.org/way/373491941
# https://www.openstreetmap.org/relation/5549623
#assert_has_feature(
#    10, 171, 396, 'roads',
#    { 'kind': 'path', 'walking_network': 'rwn'})

# highway=path, with route regional (Merced Pass Trail) at zoom 10
# https://www.openstreetmap.org/way/39996451
# https://www.openstreetmap.org/relation/5549623
#assert_has_feature(
#    10, 172, 396, 'roads',
#    { 'kind': 'path', 'walking_network': 'rwn'})

# highway=unclassified, with route local (Grant Avenue) at zoom 12
# part of The Barbary Coast Trail in San Francisco
# https://www.openstreetmap.org/way/91181758
# https://www.openstreetmap.org/relation/6322028
#assert_has_feature(
#    12, 688, 1584, 'roads',
#    { 'kind': 'minor_road', 'walking_network': 'lwn'})

# Way: Clara-Immerwahr-Straße (287167007)
# icn=yes is marked on the way
# http://www.openstreetmap.org/way/287167007
# assert_has_feature(
#     8, 134, 85, 'roads',
#     { 'kind': 'minor_road', 'bicycle_network': 'icn'})

# Ferry between Denmark and Germany, icn
# https://www.openstreetmap.org/way/128631318
# https://www.openstreetmap.org/relation/721738
#assert_has_feature(
#     8, 136, 81, 'roads',
#     { 'kind': 'ferry', 'bicycle_network': 'icn'})

# Søndervangsvej minor road in Denmark as national cycle route
# https://www.openstreetmap.org/way/149701891
# https://www.openstreetmap.org/relation/349521
#assert_has_feature(
#     8, 136, 79, 'roads',
#     { 'kind': 'minor_road', 'bicycle_network': 'ncn'})

# Part of Bay Trail in South (San Francisco) Bay
# way is marked rcn=yes, and part of a proper bike relation
# http://www.openstreetmap.org/way/44422697
# http://www.openstreetmap.org/relation/325779
#assert_has_feature(
#     10, 164, 396, 'roads',
#     { 'kind': 'path', 'bicycle_network': 'rcn'})

# Hyltebjerg Allé residential road with rcn in Copenhagen
# https://www.openstreetmap.org/way/2860759
# https://www.openstreetmap.org/relation/2087590
#assert_has_feature(
#     10, 1095, 641, 'roads',
#     { 'kind': 'minor_road', 'bicycle_network': 'rcn'})

# lcn in Seattle (living street that would only be visible at zoom 13 otherwise) at zoom 11
# https://www.openstreetmap.org/way/6477775
# https://www.openstreetmap.org/relation/3541926
assert_has_feature(
    11, 327, 715, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})

# Kirkham Street lcn in San Francisco at zoom 11
# https://www.openstreetmap.org/way/89802424
# https://www.openstreetmap.org/relation/32313
assert_has_feature(
    11, 327, 791, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})

# Asiatisk Plads service road with lcn in Copenhagen
# https://www.openstreetmap.org/way/164049387
# https://www.openstreetmap.org/relation/6199242
assert_has_feature(
    11, 1095, 641, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})
<commit_msg>[tests] add back in z10 bike routes<commit_after># highway=path, with route national (Pacific Crest Trail) at zoom 9
# https://www.openstreetmap.org/way/236361475
# https://www.openstreetmap.org/relation/1225378
assert_has_feature(
    9, 86, 197, 'roads',
    { 'kind': 'path', 'walking_network': 'nwn'})

# highway=path, with route regional (Merced Pass Trail) at zoom 10
# https://www.openstreetmap.org/way/373491941
# https://www.openstreetmap.org/relation/5549623
#assert_has_feature(
#    10, 171, 396, 'roads',
#    { 'kind': 'path', 'walking_network': 'rwn'})

# highway=path, with route regional (Merced Pass Trail) at zoom 10
# https://www.openstreetmap.org/way/39996451
# https://www.openstreetmap.org/relation/5549623
#assert_has_feature(
#    10, 172, 396, 'roads',
#    { 'kind': 'path', 'walking_network': 'rwn'})

# highway=unclassified, with route local (Grant Avenue) at zoom 12
# part of The Barbary Coast Trail in San Francisco
# https://www.openstreetmap.org/way/91181758
# https://www.openstreetmap.org/relation/6322028
#assert_has_feature(
#    12, 688, 1584, 'roads',
#    { 'kind': 'minor_road', 'walking_network': 'lwn'})

# Way: Clara-Immerwahr-Straße (287167007)
# icn=yes is marked on the way
# http://www.openstreetmap.org/way/287167007
# assert_has_feature(
#     8, 134, 85, 'roads',
#     { 'kind': 'minor_road', 'bicycle_network': 'icn'})

# Ferry between Denmark and Germany, icn
# https://www.openstreetmap.org/way/128631318
# https://www.openstreetmap.org/relation/721738
#assert_has_feature(
#     8, 136, 81, 'roads',
#     { 'kind': 'ferry', 'bicycle_network': 'icn'})

# Søndervangsvej minor road in Denmark as national cycle route
# https://www.openstreetmap.org/way/149701891
# https://www.openstreetmap.org/relation/349521
#assert_has_feature(
#     8, 136, 79, 'roads',
#     { 'kind': 'minor_road', 'bicycle_network': 'ncn'})

# Part of Bay Trail in South (San Francisco) Bay
# way is marked rcn=yes, and part of a proper bike relation
# http://www.openstreetmap.org/way/44422697
# http://www.openstreetmap.org/relation/325779
assert_has_feature(
    10, 164, 396, 'roads',
    { 'kind': 'path', 'bicycle_network': 'rcn'})

# Hyltebjerg Allé residential road with rcn in Copenhagen
# https://www.openstreetmap.org/way/2860759
# https://www.openstreetmap.org/relation/2087590
assert_has_feature(
    10, 1095, 641, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'rcn'})

# lcn in Seattle (living street that would only be visible at zoom 13 otherwise) at zoom 11
# https://www.openstreetmap.org/way/6477775
# https://www.openstreetmap.org/relation/3541926
assert_has_feature(
    11, 327, 715, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})

# Kirkham Street lcn in San Francisco at zoom 11
# https://www.openstreetmap.org/way/89802424
# https://www.openstreetmap.org/relation/32313
assert_has_feature(
    11, 327, 791, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})

# Asiatisk Plads service road with lcn in Copenhagen
# https://www.openstreetmap.org/way/164049387
# https://www.openstreetmap.org/relation/6199242
assert_has_feature(
    11, 1095, 641, 'roads',
    { 'kind': 'minor_road', 'bicycle_network': 'lcn'})
<|endoftext|>


<commit_before># -*- coding: utf8 -*-
"""
.. module:: lesscpy.plib.deferred
    :synopsis: Deferred mixin call.

    Copyright (c)
    See LICENSE for details.
.. moduleauthor:: Jóhann T. Maríusson <jtm@robot.is>
"""
from .node import Node
from lesscpy.lessc import utility

class Deferred(Node):
    def __init__(self, mixin, args, lineno=0):
        """This node represents mixin calls. The calls
        to these mixins are deferred until the second
        parse cycle. lessc.js allows calls to mixins not
        yet defined or known.
        args:
            mixin (Mixin): Mixin object
            args (list): Call arguments
        """
        self.tokens = [mixin, args]
        self.lineno = lineno

    def parse(self, scope, error=False):
        """ Parse function. We search for mixins
        first within current scope then fallback
        to global scope. The special scope.deferred
        is used when local scope mixins are called
        within parent mixins.
        If nothing is found we fallback to block-mixin
        as lessc.js allows calls to blocks and mixins to
        be inter-changable.
        clx: This method is a HACK that stems from
        poor design elsewhere. I will fix it
        when I have more time.
        args:
            scope (Scope): Current scope
        returns:
            mixed
        """
        res = False
        ident, args = self.tokens
        ident.parse(scope)
        mixins = scope.mixins(ident.raw())

        if not mixins:
            ident.parse(None)
            mixins = scope.mixins(ident.raw())

        if not mixins:
            if scope.deferred:
                store = [t for t in scope.deferred.parsed[-1]]
                while scope.deferred.parsed[-1]:
                    scope.current = scope.deferred
                    ident.parse(scope)
                    mixins = scope.mixins(ident.raw())
                    scope.current = None
                    if mixins:
                        break
                    scope.deferred.parsed[-1].pop()
                scope.deferred.parsed[-1] = store

        if not mixins:
            # Fallback to blocks
            block = scope.blocks(ident.raw())
            if not block:
                ident.parse(None)
                block = scope.blocks(ident.raw())
            if block:
                scope.current = scope.real[-1] if scope.real else None
                res = block.copy_inner(scope)
                scope.current = None

        if mixins:
            for mixin in mixins:
                scope.current = scope.real[-1] if scope.real else None
                res = mixin.call(scope, args)
                if res:
                    # Add variables to scope to support
                    # closures
                    [scope.add_variable(v) for v in mixin.vars]
                    scope.deferred = ident
                    break

        if res:
            res = [p.parse(scope) for p in res if p]
            while(any(t for t in res if type(t) is Deferred)):
                res = [p.parse(scope) for p in res if p]

        if error and not res:
            raise SyntaxError('NameError `%s`' % mixin.raw(True))
        return res

    def copy(self):
        """ Returns self (used when Block objects are copy'd)
        returns:
            self
        """
        return self

<commit_msg>Fix scoping problems<commit_after># -*- coding: utf8 -*-
"""
.. module:: lesscpy.plib.deferred
    :synopsis: Deferred mixin call.

    Copyright (c)
    See LICENSE for details.
.. moduleauthor:: Jóhann T. Maríusson <jtm@robot.is>
"""
from .node import Node
from lesscpy.lessc import utility

class Deferred(Node):
    def __init__(self, mixin, args, lineno=0):
        """This node represents mixin calls. The calls
        to these mixins are deferred until the second
        parse cycle. lessc.js allows calls to mixins not
        yet defined or known.
        args:
            mixin (Mixin): Mixin object
            args (list): Call arguments
        """
        self.tokens = [mixin, args]
        self.lineno = lineno

    def parse(self, scope, error=False):
        """ Parse function. We search for mixins
        first within current scope then fallback
        to global scope. The special scope.deferred
        is used when local scope mixins are called
        within parent mixins.
        If nothing is found we fallback to block-mixin
        as lessc.js allows calls to blocks and mixins to
        be inter-changable.
        clx: This method is a HACK that stems from
        poor design elsewhere. I will fix it
        when I have more time.
        args:
            scope (Scope): Current scope
        returns:
            mixed
        """
        res = False
        ident, args = self.tokens
        ident.parse(scope)
        mixins = scope.mixins(ident.raw())

        if not mixins:
            ident.parse(None)
            mixins = scope.mixins(ident.raw())

        if not mixins:
            if scope.deferred:
                store = [t for t in scope.deferred.parsed[-1]]
                while scope.deferred.parsed[-1]:
                    scope.current = scope.deferred
                    ident.parse(scope)
                    mixins = scope.mixins(ident.raw())
                    scope.current = None
                    if mixins:
                        break
                    scope.deferred.parsed[-1].pop()
                scope.deferred.parsed[-1] = store

        if not mixins:
            # Fallback to blocks
            block = scope.blocks(ident.raw())
            if not block:
                ident.parse(None)
                block = scope.blocks(ident.raw())
            if block:
                scope.current = scope.real[-1] if scope.real else None
                res = block.copy_inner(scope)
                scope.current = None

        if mixins:
            for mixin in mixins:
                scope.current = scope.real[-1] if scope.real else None
                res = mixin.call(scope, args)
                if res:
                    # Add variables to scope to support
                    # closures
                    [scope.add_variable(v) for v in mixin.vars]
                    scope.deferred = ident
                    break

        if res:
            store = [t for t in scope.deferred.parsed[-1]] if scope.deferred else False
            res = [p.parse(scope) for p in res if p]
            while(any(t for t in res if type(t) is Deferred)):
                res = [p.parse(scope) for p in res if p]
            if store: scope.deferred.parsed[-1] = store

        if error and not res:
            raise SyntaxError('NameError `%s`' % ident.raw(True))
        return res

    def copy(self):
        """ Returns self (used when Block objects are copy'd)
        returns:
            self
        """
        return self

<|endoftext|>


<commit_before>"""ARs and Samples use HeaderTable to display object fields in their custom
view and edit screens.
"""

from bika.lims.browser import BrowserView
from bika.lims.interfaces import IHeaderTableFieldRenderer
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.CMFPlone import PloneMessageFactory as _p
from zope.component import getAdapter
from AccessControl import getSecurityManager
from AccessControl.Permissions import view
from zope.component.interfaces import ComponentLookupError

class HeaderTableView(BrowserView):

    template = ViewPageTemplateFile('templates/header_table.pt')

    def __call__(self):
        self.errors = {}
        if 'header_table_submitted' in self.request:
            schema = self.context.Schema()
            fields = schema.fields()
            form = self.request.form
            for field in fields:
                fieldname = field.getName()
                if fieldname in form:
                    if fieldname + "_uid" in form:
                        # references (process_form would normally do *_uid trick)
                        field.getMutator(self.context)(form[fieldname + "_uid"])
                    else:
                        # other fields
                        field.getMutator(self.context)(form[fieldname])
            message = _p("Changes saved.")
            self.context.plone_utils.addPortalMessage(message, 'info')
        return self.template()

    def three_column_list(self, input_list):
        list_len = len(input_list)

        # Calculate the length of the sublists
        sublist_len = (list_len % 3 == 0 and list_len / 3 or list_len / 3 + 1)

        def _list_end(num):
            # Calculate the list end point given the list number
            return (num == 2 and list_len or (num + 1) * sublist_len)

        # Generate only filled columns
        final = []
        for i in range(3):
            column = input_list[i * sublist_len:_list_end(i)]
            if len(column) > 0:
                final.append(column)
        return final

    def render_field_view(self, fieldname):
        field = self.context.Schema()[fieldname]
        ret = {'fieldName': fieldname, 'mode': 'view'}
        try:
            adapter = getAdapter(self.context,
                                 interface=IHeaderTableFieldRenderer,
                                 name=fieldname)
        except ComponentLookupError:
            adapter = None
        if adapter:
            ret = {'fieldName': fieldname,
                   'mode': 'structure',
                   'html': adapter(field)}
        else:
            if field.getType().find("Reference") > -1:
                targets = field.get(self.context)
                if targets:
                    if not type(targets) == list:
                        targets = [targets,]
                    sm = getSecurityManager()
                    if all([sm.checkPermission(view, t) for t in targets]):
                        a = ["%s" % (target.absolute_url(),
                                                      target.Title())
                             for target in targets]
                        ret = {'fieldName': fieldname,
                               'mode': 'structure',
                               'html': ", ".join(a)}
                    else:
                        ret = {'fieldName': fieldname,
                               'mode': 'structure',
                               'html': ", ".join([t.Title() for t in targets])}
                else:
                    ret = {'fieldName': fieldname,
                           'mode': 'structure',
                           'html': ''}
        return ret

    def sublists(self, mode):
        ret = []
        prominent = []
        adapter = getAdapter(self.context, name='getWidgetVisibility')
        wv = adapter()
        new_wv = {}
        # respect schemaextender's re-ordering of fields
        schema_fields = [f.getName() for f in self.context.Schema().fields()]
        for viewname, state_field_lists in wv.items():
            new_wv[mode] = {}
            for statename, state_fields in state_field_lists.items():
                print statename, state_fields
                new_wv[mode][statename] = \
                    [field for field in schema_fields if field in state_fields]
        edit_fields = new_wv.get('edit_fields', {}).get('visible', [])
        view_fields = new_wv.get('view_fields', {}).get('visible', [])
        # Prominent fields get appended
        prominent_fieldnames = new_wv.get('header_table', {}).get('prominent', [])
        for fieldname in prominent_fieldnames:
            if fieldname in view_fields:
                prominent.append(self.render_field_view(fieldname))
            elif fieldname in edit_fields:
                prominent.append({'fieldName': fieldname, 'mode': 'edit_fields'})
        # Other visible fields get appended
        visible_fieldnames = new_wv.get('header_table', {}).get('visible', [])
        for fieldname in visible_fieldnames:
            if fieldname in prominent_fieldnames:
                continue
            if fieldname in edit_fields:
                ret.append({'fieldName': fieldname, 'mode': 'edit_fields'})
            elif fieldname in view_fields:
                ret.append(self.render_field_view(fieldname))
        return prominent, self.three_column_list(ret)
<commit_msg>Fix for df9f965<commit_after>"""ARs and Samples use HeaderTable to display object fields in their custom
view and edit screens.
"""

from bika.lims.browser import BrowserView
from bika.lims.interfaces import IHeaderTableFieldRenderer
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.CMFPlone import PloneMessageFactory as _p
from zope.component import getAdapter
from AccessControl import getSecurityManager
from AccessControl.Permissions import view
from zope.component.interfaces import ComponentLookupError

class HeaderTableView(BrowserView):

    template = ViewPageTemplateFile('templates/header_table.pt')

    def __call__(self):
        self.errors = {}
        if 'header_table_submitted' in self.request:
            schema = self.context.Schema()
            fields = schema.fields()
            form = self.request.form
            for field in fields:
                fieldname = field.getName()
                if fieldname in form:
                    if fieldname + "_uid" in form:
                        # references (process_form would normally do *_uid trick)
                        field.getMutator(self.context)(form[fieldname + "_uid"])
                    else:
                        # other fields
                        field.getMutator(self.context)(form[fieldname])
            message = _p("Changes saved.")
            self.context.plone_utils.addPortalMessage(message, 'info')
        return self.template()

    def three_column_list(self, input_list):
        list_len = len(input_list)

        # Calculate the length of the sublists
        sublist_len = (list_len % 3 == 0 and list_len / 3 or list_len / 3 + 1)

        def _list_end(num):
            # Calculate the list end point given the list number
            return num == 2 and list_len or (num + 1) * sublist_len

        # Generate only filled columns
        final = []
        for i in range(3):
            column = input_list[i * sublist_len:_list_end(i)]
            if len(column) > 0:
                final.append(column)
        return final

    def render_field_view(self, fieldname):
        field = self.context.Schema()[fieldname]
        ret = {'fieldName': fieldname, 'mode': 'view'}
        try:
            adapter = getAdapter(self.context,
                                 interface=IHeaderTableFieldRenderer,
                                 name=fieldname)
        except ComponentLookupError:
            adapter = None
        if adapter:
            ret = {'fieldName': fieldname,
                   'mode': 'structure',
                   'html': adapter(field)}
        else:
            if field.getType().find("Reference") > -1:
                targets = field.get(self.context)
                if targets:
                    if not type(targets) == list:
                        targets = [targets,]
                    sm = getSecurityManager()
                    if all([sm.checkPermission(view, t) for t in targets]):
                        a = ["%s" % (target.absolute_url(),
                                                      target.Title())
                             for target in targets]
                        ret = {'fieldName': fieldname,
                               'mode': 'structure',
                               'html': ", ".join(a)}
                    else:
                        ret = {'fieldName': fieldname,
                               'mode': 'structure',
                               'html': ", ".join([t.Title() for t in targets])}
                else:
                    ret = {'fieldName': fieldname,
                           'mode': 'structure',
                           'html': ''}
        return ret

    def sublists(self):
        ret = []
        prominent = []
        adapter = getAdapter(self.context, name='getWidgetVisibility')
        wv = adapter()
        new_wv = {}
        # respect schemaextender's re-ordering of fields
        schema_fields = [f.getName() for f in self.context.Schema().fields()]
        for mode, state_field_lists in wv.items():
            new_wv[mode] = {}
            for statename, state_fields in state_field_lists.items():
                new_wv[mode][statename] = \
                    [field for field in schema_fields if field in state_fields]
        edit_fields = new_wv.get("edit", {}).get('visible', [])
        view_fields = new_wv.get("view", {}).get('visible', [])
        # Prominent fields get appended
        prominent_fieldnames = new_wv.get('header_table', {}).get('prominent', [])
        for fieldname in prominent_fieldnames:
            if fieldname in view_fields:
                prominent.append(self.render_field_view(fieldname))
            elif fieldname in edit_fields:
                prominent.append({'fieldName': fieldname, 'mode': "edit"})
        # Other visible fields get appended
        visible_fieldnames = new_wv.get('header_table', {}).get('visible', [])
        for fieldname in visible_fieldnames:
            if fieldname in prominent_fieldnames:
                continue
            if fieldname in edit_fields:
                ret.append({'fieldName': fieldname, 'mode': "edit"})
            elif fieldname in view_fields:
                ret.append(self.render_field_view(fieldname))
        return prominent, self.three_column_list(ret)
<|endoftext|>


<commit_before>#!/usr/bin/env python

__author__ = 'Stephen P. Henrie, Michael Meisinger'
__license__ = 'Apache 2.0'

from mock import Mock, patch
from nose.plugins.attrib import attr

from pyon.core.exception import BadRequest, Conflict, Inconsistent, NotFound
from pyon.public import PRED, RT, IonObject, OT, log
from pyon.util.context import LocalContextMixin
from pyon.util.int_test import IonIntegrationTestCase
from pyon.util.unit_test import PyonTestCase

from ion.services.coi.resource_management_service import ResourceManagementService

from interface.services.coi.iresource_management_service import ResourceManagementServiceClient, ResourceManagementServiceProcessClient
from interface.services.coi.iobject_management_service import ObjectManagementServiceClient

@attr('UNIT', group='coi')
class TestResourceManagementServiceUnit(PyonTestCase):

    def setUp(self):
        mock_clients = self._create_service_mock('resource_management')
        self.rms = ResourceManagementService()
        self.rms.clients = mock_clients
        self.object_definition = '''
Policy9: !Extends_InformationResource
  enabled: True
  definition: {}
'''

    def test_create_resource(self):
        # Create ResourceType
        rt = Mock()
        rt.name = "bad name"
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt, "123")

        rt.name = "good_name"
        bad_object_id = None
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt, bad_object_id)

        # Create ObjectType
        ot = Mock()
        ot.definition = self.object_definition
        ot.name = "good_name"
        ot.description = "This is just a test. No need to panic"

        self.rms.clients.resource_registry.read.return_value = ot
        resource_id_return_value = '123'
        version_return_value = 1
        self.rms.clients.resource_registry.create.return_value = [resource_id_return_value, version_return_value]
        self.rms.clients.resource_registry.create_association.return_value = '999'

        object_id = "444"
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertEqual(resource_id, '123')

        self.rms.clients.resource_registry.read.assert_called_once_with(object_id, '')
        self.rms.clients.resource_registry.create.assert_called_once_with(rt)
        self.rms.clients.resource_registry.create_association.assert_called_once_with(resource_id_return_value, PRED.hasObjectType, object_id, 'H2H')

    def test_read_resource(self):
        with self.assertRaises(BadRequest):
            self.rms.read_resource_type(None)
        # Create ResourceType
        rt = Mock()
        rt.name = "good_name"
        self.rms.clients.resource_registry.read.return_value = rt

        rt_read = self.rms.read_resource_type("123")
        self.assertTrue(rt_read is rt)
        self.rms.clients.resource_registry.read.assert_called_once_with('123','')

    def test_read_not_found(self):
        self.rms.clients.resource_registry.read.side_effect = NotFound
        with self.assertRaises(NotFound):
            self.rms.read_resource_type("0xBadC0ffee")
        self.rms.clients.resource_registry.read.assert_called_once_with("0xBadC0ffee", '')

    def test_delete_resource(self):
        with self.assertRaises(BadRequest):
            self.rms.delete_resource_type(None, "123")

        with self.assertRaises(BadRequest):
            self.rms.delete_resource_type("123", None)

        self.rms.clients.resource_registry.delete.return_value = True
        association_id = '999'
        self.rms.clients.resource_registry.get_association.return_value = association_id
        self.rms.clients.resource_registry.delete_association.return_value = True
        resource_id = '123'
        object_id = '456'
        status = self.rms.delete_resource_type(resource_id, object_id)
        self.assertTrue(status, True)
        self.rms.clients.resource_registry.delete.assert_called_once_with(resource_id)
        self.rms.clients.resource_registry.get_association.assert_called_once_with(resource_id, PRED.hasObjectType, object_id, None, False)
        self.rms.clients.resource_registry.delete_association.assert_called_once_with(association_id)

    def test_delete_not_found(self):
        self.rms.clients.resource_registry.get_association.side_effect = NotFound
        resource_id = "123"
        object_id = '456'
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)
        self.rms.clients.resource_registry.get_association.assert_called_once_with(resource_id, PRED.hasObjectType, object_id, None, False)

        association_id = '999'
        self.rms.clients.resource_registry.delete.side_effect = NotFound
        self.rms.clients.resource_registry.get_association.side_effect = None
        self.rms.clients.resource_registry.get_association.return_value = association_id
        self.rms.clients.resource_registry.delete_association.return_value = True
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)
        self.rms.clients.resource_registry.get_association.assert_called_with(resource_id, PRED.hasObjectType, object_id, None, False)
        self.rms.clients.resource_registry.delete_association.assert_called_with(association_id)
        self.rms.clients.resource_registry.delete.assert_called_with(resource_id)

@attr('INT', group='coi')
class TestResourceManagementService(IonIntegrationTestCase):

    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.rms = ResourceManagementServiceClient()
        self.oms = ObjectManagementServiceClient()

    def test_create_and_delete_resource(self):
        object_definition = '''
Policy2: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt,'')
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Cleanup by deleting the ObjectType and ResourceType
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

    def test_read_resource(self):
        object_definition = '''
Policy3: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)
        with self.assertRaises(BadRequest):
            self.rms.read_resource_type("")

        # Cleanup by deleting the ObjectType and the ResourceType
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

    def test_read_resource_not_found(self):
        object_definition = '''
Policy4: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)

        # Delete
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

        # Read ResourceType that has been deleted
        with self.assertRaises(NotFound):
            self.rms.read_resource_type(resource_id)

    def test_delete_resource_not_found(self):
        object_definition = '''
Policy5: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)

        # Delete
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

        # Delete a ResourceType that has already been deleted
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)

class FakeProcess(LocalContextMixin):
    """
    A fake process used because the test case is not an ion process.
    """
    name = ''
    id=''
    process_type = ''

@attr('INT', group='rms')
class TestResourceManagementServiceInterface(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')

        # Now create client to service
        self.rr = self.container.resource_registry
        fp = FakeProcess()

        self.rms = ResourceManagementServiceProcessClient(process=fp)

    def test_resource_interface(self):
        rid1,_ = self.rr.create(IonObject('Resource', name='res1'))

        cap_list = self.rms.get_capabilities(rid1)
        log.warn("Capabilities: %s", cap_list)
        self.assertTrue(type(cap_list) is list)

        get_res = self.rms.get_resource(rid1, params=['object_size'])
        log.warn("Get result: %s", get_res)

        self.rms.set_resource(rid1, params={'description': 'NEWDESC'})
        res_obj = self.rr.read(rid1)
        self.assertEquals(res_obj.description, 'NEWDESC')

        self.rr.delete(rid1)

        # Test CRUD
        with self.assertRaises(BadRequest):
            self.rms.create_resource(IonObject('StreamConfiguration', stream_name='res2'))

        rid2 = self.rms.create_resource(IonObject('Resource', name='res2'))
        res_obj = self.rr.read(rid2)
        self.assertEquals(res_obj.name, 'res2')

        with self.assertRaises(BadRequest):
            self.rms.update_resource(IonObject('StreamConfiguration', stream_name='res2'))
        res_obj.description = 'DESC2'
        self.rms.update_resource(res_obj)
        res_obj = self.rr.read(rid2)
        self.assertEquals(res_obj.description, 'DESC2')

        res_obj2 = self.rms.read_resource(rid2)
        self.assertEquals(res_obj.description, res_obj2.description)

        with self.assertRaises(BadRequest):
            self.rms.get_resource_state(rid2)
        with self.assertRaises(BadRequest):
            self.rms.ping_resource(rid2)
        with self.assertRaises(BadRequest):
            self.rms.get_agent(rid2)
        with self.assertRaises(BadRequest):
            self.rms.get_agent_state(rid2)

        self.rms.delete_resource(rid2)

        rid3,_ = self.rr.create(IonObject('InstrumentDevice', name='res3'))
        rid3_r = self.rr.read(rid3)
        self.assertEquals(rid3_r.lcstate, "DRAFT_PRIVATE")

        self.rms.execute_lifecycle_transition(rid3, "plan")
        rid3_r = self.rr.read(rid3)
        self.assertEquals(rid3_r.lcstate, "PLANNED_PRIVATE")

<commit_msg>test RMS on a less restrictive resource type that still has a lifecycle<commit_after>#!/usr/bin/env python

__author__ = 'Stephen P. Henrie, Michael Meisinger'
__license__ = 'Apache 2.0'

from mock import Mock, patch
from nose.plugins.attrib import attr

from pyon.core.exception import BadRequest, Conflict, Inconsistent, NotFound
from pyon.public import PRED, RT, IonObject, OT, log
from pyon.util.context import LocalContextMixin
from pyon.util.int_test import IonIntegrationTestCase
from pyon.util.unit_test import PyonTestCase

from ion.services.coi.resource_management_service import ResourceManagementService

from interface.services.coi.iresource_management_service import ResourceManagementServiceClient, ResourceManagementServiceProcessClient
from interface.services.coi.iobject_management_service import ObjectManagementServiceClient

@attr('UNIT', group='coi')
class TestResourceManagementServiceUnit(PyonTestCase):

    def setUp(self):
        mock_clients = self._create_service_mock('resource_management')
        self.rms = ResourceManagementService()
        self.rms.clients = mock_clients
        self.object_definition = '''
Policy9: !Extends_InformationResource
  enabled: True
  definition: {}
'''

    def test_create_resource(self):
        # Create ResourceType
        rt = Mock()
        rt.name = "bad name"
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt, "123")

        rt.name = "good_name"
        bad_object_id = None
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt, bad_object_id)

        # Create ObjectType
        ot = Mock()
        ot.definition = self.object_definition
        ot.name = "good_name"
        ot.description = "This is just a test. No need to panic"

        self.rms.clients.resource_registry.read.return_value = ot
        resource_id_return_value = '123'
        version_return_value = 1
        self.rms.clients.resource_registry.create.return_value = [resource_id_return_value, version_return_value]
        self.rms.clients.resource_registry.create_association.return_value = '999'

        object_id = "444"
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertEqual(resource_id, '123')

        self.rms.clients.resource_registry.read.assert_called_once_with(object_id, '')
        self.rms.clients.resource_registry.create.assert_called_once_with(rt)
        self.rms.clients.resource_registry.create_association.assert_called_once_with(resource_id_return_value, PRED.hasObjectType, object_id, 'H2H')

    def test_read_resource(self):
        with self.assertRaises(BadRequest):
            self.rms.read_resource_type(None)
        # Create ResourceType
        rt = Mock()
        rt.name = "good_name"
        self.rms.clients.resource_registry.read.return_value = rt

        rt_read = self.rms.read_resource_type("123")
        self.assertTrue(rt_read is rt)
        self.rms.clients.resource_registry.read.assert_called_once_with('123','')

    def test_read_not_found(self):
        self.rms.clients.resource_registry.read.side_effect = NotFound
        with self.assertRaises(NotFound):
            self.rms.read_resource_type("0xBadC0ffee")
        self.rms.clients.resource_registry.read.assert_called_once_with("0xBadC0ffee", '')

    def test_delete_resource(self):
        with self.assertRaises(BadRequest):
            self.rms.delete_resource_type(None, "123")

        with self.assertRaises(BadRequest):
            self.rms.delete_resource_type("123", None)

        self.rms.clients.resource_registry.delete.return_value = True
        association_id = '999'
        self.rms.clients.resource_registry.get_association.return_value = association_id
        self.rms.clients.resource_registry.delete_association.return_value = True
        resource_id = '123'
        object_id = '456'
        status = self.rms.delete_resource_type(resource_id, object_id)
        self.assertTrue(status, True)
        self.rms.clients.resource_registry.delete.assert_called_once_with(resource_id)
        self.rms.clients.resource_registry.get_association.assert_called_once_with(resource_id, PRED.hasObjectType, object_id, None, False)
        self.rms.clients.resource_registry.delete_association.assert_called_once_with(association_id)

    def test_delete_not_found(self):
        self.rms.clients.resource_registry.get_association.side_effect = NotFound
        resource_id = "123"
        object_id = '456'
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)
        self.rms.clients.resource_registry.get_association.assert_called_once_with(resource_id, PRED.hasObjectType, object_id, None, False)

        association_id = '999'
        self.rms.clients.resource_registry.delete.side_effect = NotFound
        self.rms.clients.resource_registry.get_association.side_effect = None
        self.rms.clients.resource_registry.get_association.return_value = association_id
        self.rms.clients.resource_registry.delete_association.return_value = True
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)
        self.rms.clients.resource_registry.get_association.assert_called_with(resource_id, PRED.hasObjectType, object_id, None, False)
        self.rms.clients.resource_registry.delete_association.assert_called_with(association_id)
        self.rms.clients.resource_registry.delete.assert_called_with(resource_id)

@attr('INT', group='coi')
class TestResourceManagementService(IonIntegrationTestCase):

    def setUp(self):
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')
        self.rms = ResourceManagementServiceClient()
        self.oms = ObjectManagementServiceClient()

    def test_create_and_delete_resource(self):
        object_definition = '''
Policy2: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        with self.assertRaises(BadRequest):
            self.rms.create_resource_type(rt,'')
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Cleanup by deleting the ObjectType and ResourceType
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

    def test_read_resource(self):
        object_definition = '''
Policy3: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)
        with self.assertRaises(BadRequest):
            self.rms.read_resource_type("")

        # Cleanup by deleting the ObjectType and the ResourceType
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

    def test_read_resource_not_found(self):
        object_definition = '''
Policy4: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)

        # Delete
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

        # Read ResourceType that has been deleted
        with self.assertRaises(NotFound):
            self.rms.read_resource_type(resource_id)

    def test_delete_resource_not_found(self):
        object_definition = '''
Policy5: !Extends_InformationResource
  enabled: True
  definition: {}
'''
        # Create ObjectType
        ot = IonObject(RT.ObjectType, {"definition": object_definition})
        object_id = self.oms.create_object_type(ot)
        self.assertTrue(type(object_id) == str)

        # Create ResourceType and create association
        rt = IonObject(RT.ResourceType)
        resource_id = self.rms.create_resource_type(rt, object_id)
        self.assertTrue(type(resource_id) == str)

        # Read resource
        resource_type = self.rms.read_resource_type(resource_id)
        self.assertTrue(resource_type)

        # Delete
        self.rms.delete_resource_type(resource_id, object_id)
        self.oms.delete_object_type(object_id)

        # Delete a ResourceType that has already been deleted
        with self.assertRaises(NotFound):
            self.rms.delete_resource_type(resource_id, object_id)

class FakeProcess(LocalContextMixin):
    """
    A fake process used because the test case is not an ion process.
    """
    name = ''
    id=''
    process_type = ''

@attr('INT', group='rms')
class TestResourceManagementServiceInterface(IonIntegrationTestCase):

    def setUp(self):
        # Start container
        self._start_container()
        self.container.start_rel_from_url('res/deploy/r2deploy.yml')

        # Now create client to service
        self.rr = self.container.resource_registry
        fp = FakeProcess()

        self.rms = ResourceManagementServiceProcessClient(process=fp)

    def test_resource_interface(self):
        rid1,_ = self.rr.create(IonObject('Resource', name='res1'))

        cap_list = self.rms.get_capabilities(rid1)
        log.warn("Capabilities: %s", cap_list)
        self.assertTrue(type(cap_list) is list)

        get_res = self.rms.get_resource(rid1, params=['object_size'])
        log.warn("Get result: %s", get_res)

        self.rms.set_resource(rid1, params={'description': 'NEWDESC'})
        res_obj = self.rr.read(rid1)
        self.assertEquals(res_obj.description, 'NEWDESC')

        self.rr.delete(rid1)

        # Test CRUD
        with self.assertRaises(BadRequest):
            self.rms.create_resource(IonObject('StreamConfiguration', stream_name='res2'))

        rid2 = self.rms.create_resource(IonObject('Resource', name='res2'))
        res_obj = self.rr.read(rid2)
        self.assertEquals(res_obj.name, 'res2')

        with self.assertRaises(BadRequest):
            self.rms.update_resource(IonObject('StreamConfiguration', stream_name='res2'))
        res_obj.description = 'DESC2'
        self.rms.update_resource(res_obj)
        res_obj = self.rr.read(rid2)
        self.assertEquals(res_obj.description, 'DESC2')

        res_obj2 = self.rms.read_resource(rid2)
        self.assertEquals(res_obj.description, res_obj2.description)

        with self.assertRaises(BadRequest):
            self.rms.get_resource_state(rid2)
        with self.assertRaises(BadRequest):
            self.rms.ping_resource(rid2)
        with self.assertRaises(BadRequest):
            self.rms.get_agent(rid2)
        with self.assertRaises(BadRequest):
            self.rms.get_agent_state(rid2)

        self.rms.delete_resource(rid2)

        rid3,_ = self.rr.create(IonObject('InstrumentAgent', name='res3'))
        rid3_r = self.rr.read(rid3)
        self.assertEquals(rid3_r.lcstate, "DRAFT_PRIVATE")

        self.rms.execute_lifecycle_transition(rid3, "plan")
        rid3_r = self.rr.read(rid3)
        self.assertEquals(rid3_r.lcstate, "PLANNED_PRIVATE")

<|endoftext|>


<commit_before>from django.urls import reverse
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.test import APITestCase, APIClient
from billjobs.tests.generics import GenericAPIStatusCode

class GenericAPITest(APITestCase):
    """
    Generic Test class to test an API endpoint
    """
    fixtures = ['test_api_user.yaml']

    def setUp(self):
        self.url = None
        self.client = APIClient()
        self.admin = User.objects.get(pk=1)
        self.user = User.objects.get(pk=2)
        self.data = {
                'create': None,
                'update': None,
                }
        self.expected_status = {
                'GET': None,
                'POST': None,
                'PUT': None,
                'DELETE': None,
                'OPTION': None,
                'HEAD': None,
                'PATCH': None,
                }

    def status_code_is(self):
        for method, status_code in self.expected_status.items():
            if method == 'GET':
                response = self.client.get(self.url, format='json')
            elif method == 'POST':
                response = self.client.post(
                        self.url, self.data['create'], format='json')
            elif method == 'PUT':
                response = self.client.put(
                        self.url, self.data['update'], format='json')
            elif method == 'DELETE':
                response = self.client.delete(self.url, format='json')
            elif method == 'HEAD':
                response = self.client.head(self.url, format='json')

            self.assertEqual(response.status_code, status_code,
                    '{0} method expected status code {1}'.format(
                        method, status_code)
                    )

class AnonymousGroupAPITest(GenericAPITest):
    """
    Test group api test
    """

    def setUp(self):
        super().setUp()
        self.url = reverse('groups-api')
        self.data = {
                'create': {'name': 'group name'},
                'update': {'name': 'new name'}
                }
        self.expected_status = {
                'GET': 401,
                'POST': 401,
                'PUT': 401,
                'DELETE': 401,
                }

    def test_group_api_status_code(self):
        self.status_code_is()

class GroupAPIAnonymousStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for anonymous user
    Permissions are tested in tests_api.py
    """

    def setUp(self):
        super().setUp()
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, None, status.HTTP_405_METHOD_NOT_ALLOWED)

class GroupAPIUserStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for user
    Permissions are tested in tests_api.py
    """

    def setUp(self):
        super().setUp()
        super().force_authenticate(self.user)
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, None, status.HTTP_405_METHOD_NOT_ALLOWED)

class GroupAPIAdminStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for admin
    """

    def setUp(self):
        super().setUp()
        super().force_authenticate(self.admin)
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, self.data,
                status.HTTP_405_METHOD_NOT_ALLOWED
                )
<commit_msg>test group api HEAD method status code for anonymous is 401<commit_after>from django.urls import reverse
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.test import APITestCase, APIClient
from billjobs.tests.generics import GenericAPIStatusCode

class GenericAPITest(APITestCase):
    """
    Generic Test class to test an API endpoint
    """
    fixtures = ['test_api_user.yaml']

    def setUp(self):
        self.url = None
        self.client = APIClient()
        self.admin = User.objects.get(pk=1)
        self.user = User.objects.get(pk=2)
        self.data = {
                'create': None,
                'update': None,
                }
        self.expected_status = {
                'GET': None,
                'POST': None,
                'PUT': None,
                'DELETE': None,
                'OPTION': None,
                'HEAD': None,
                'PATCH': None,
                }

    def status_code_is(self):
        for method, status_code in self.expected_status.items():
            if method == 'GET':
                response = self.client.get(self.url, format='json')
            elif method == 'POST':
                response = self.client.post(
                        self.url, self.data['create'], format='json')
            elif method == 'PUT':
                response = self.client.put(
                        self.url, self.data['update'], format='json')
            elif method == 'DELETE':
                response = self.client.delete(self.url, format='json')
            elif method == 'HEAD':
                response = self.client.head(self.url, format='json')

            self.assertEqual(response.status_code, status_code,
                    '{0} method expected status code {1}'.format(
                        method, status_code)
                    )

class AnonymousGroupAPITest(GenericAPITest):
    """
    Test group api test
    """

    def setUp(self):
        super().setUp()
        self.url = reverse('groups-api')
        self.data = {
                'create': {'name': 'group name'},
                'update': {'name': 'new name'}
                }
        self.expected_status = {
                'GET': 401,
                'POST': 401,
                'PUT': 401,
                'DELETE': 401,
                'HEAD': 401,
                }

    def test_group_api_status_code(self):
        self.status_code_is()

class GroupAPIAnonymousStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for anonymous user
    Permissions are tested in tests_api.py
    """

    def setUp(self):
        super().setUp()
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, None, status.HTTP_405_METHOD_NOT_ALLOWED)

class GroupAPIUserStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for user
    Permissions are tested in tests_api.py
    """

    def setUp(self):
        super().setUp()
        super().force_authenticate(self.user)
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, None, status.HTTP_405_METHOD_NOT_ALLOWED)

class GroupAPIAdminStatusCode(GenericAPIStatusCode):
    """
    Tests status code returned by /groups endpoint for admin
    """

    def setUp(self):
        super().setUp()
        super().force_authenticate(self.admin)
        self.url = self.endpoints['groups']
        self.data = {'name': 'group name'}

    def test_api_group_put_is_405(self):
        """
        Test group api with PUT method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'PUT', self.url, self.data, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_api_group_delete_is_405(self):
        """
        Test group api with DELETE method return HTTP_405_METHOD_NOT_ALLOWED
        """
        super().status_code_is(
                'DELETE', self.url, self.data,
                status.HTTP_405_METHOD_NOT_ALLOWED
                )
<|endoftext|>


<commit_before><commit_msg>remove models folder<commit_after><|endoftext|>


<commit_before>import shutil
from Classes.Manifest import Manifest
from .Input import InputSample
from .Filtering import FilteringSample
from .Sink import SinkSample
from .ExecQuery import ExecQuerySample
from .Complexity import ComplexitySample
from .MainClass import MainClassSample
from Classes.FileManager import FileManager
import xml.etree.ElementTree as ET

class Generator():

    MAX_RECURSION = 1
    # HACK  >=0 : generate NUMBER_GENERATE of trio (input,filtering,sink) , -1 : unlimited
    NUMBER_GENERATE = -1

    def __init__(self, date):
        self.date = date
        # TODO:60 readd this for manifest generation
        # self.manifest = Manifest(date, flaw)
        self.safe_Sample = 0
        self.unsafe_Sample = 0
        self.flaw_type_user = None
        self.flaw_group_user = None
        # parse XML files
        tree_input = ET.parse(FileManager.getXML("input")).getroot()
        self.tab_input = [InputSample(inp) for inp in tree_input]
        tree_filtering = ET.parse(FileManager.getXML("filtering")).getroot()
        self.tab_filtering = [FilteringSample(filtering) for filtering in tree_filtering]
        tree_sink = ET.parse(FileManager.getXML("sink")).getroot()
        self.tab_sink = [SinkSample(sink) for sink in tree_sink]
        tree_exec_query = ET.parse(FileManager.getXML("exec_queries")).getroot()
        self.tab_exec_queries = [ExecQuerySample(exec_query) for exec_query in tree_exec_query]
        tree_complexities = ET.parse(FileManager.getXML("complexities")).getroot()
        self.tab_complexity = [ComplexitySample(complexity) for complexity in tree_complexities.find("complexities")]
        self.main_class = MainClassSample(ET.parse(FileManager.getXML("main_class")).getroot())
        # set current samples
        self.current_input = None
        self.current_filtering = None
        self.current_sink = None
        self.current_exec_queries = None
        self.current_code = None
        # HACK
        self.number_generate = Generator.NUMBER_GENERATE

    def get_group_list(self):
        return {sink.flaw_group.upper() for sink in self.tab_sink}

    def get_cwe_list(self):
        return {sink.flaw_type_number() for sink in self.tab_sink}

    def is_safe_selection(self):
        return (self.current_input.is_safe(self.current_sink.flaw_type)
                or self.current_filtering.is_safe(self.current_sink.flaw_type) or
                self.current_sink.safe)

    def generate(self):
        self.select_sink()

    # fist step : browse sink
    def select_sink(self):
        for sink in self.tab_sink:
            if ((not self.flaw_type_user or sink.flaw_type_number() in self.flaw_type_user)
               and (not self.flaw_group_user or sink.flaw_group in self.flaw_group_user)):
                self.current_sink = sink
                self.select_filtering()

    # second step : browse filtering
    def select_filtering(self):
        # select filtering
        for filtering in self.tab_filtering:
            self.current_filtering = filtering
            # check if sink and filtering are compatibles
            if filtering.compatible_with_sink(self.current_sink):
                self.select_input()

    # third step : browse input
    def select_input(self):
        # select input
        for inp in self.tab_input:
            if inp.compatible_with_filtering_sink(self.current_filtering, self.current_sink):
                self.current_input = inp
                self.recursion_level()

    # fouth step : compute recursion level
    def recursion_level(self):
        # HACK
        if self.number_generate == 0:
            return
        self.number_generate -= 1

        for i in range(0, Generator.MAX_RECURSION+1):
            self.select_complexities(i)

    # fourth step bis : browse complexities
    def select_complexities(self, level):
        print(level)
        if level == 0:
            self.select_exec_queries()
        else:
            # Select complexity for this level
            for complexity in self.tab_complexity:
                self.select_complexities(level-1)

    # fifth step : browse exec_queries
    def select_exec_queries(self):
        if self.current_sink.need_exec():
            # select exec_queries
            for exec_query in self.tab_exec_queries:
                if self.current_sink.compatible_with_exec_queries(exec_query):
                    self.current_exec_queries = exec_query
                    self.compose()
        else:
            self.current_exec_queries = None
            self.compose()

    # seventh step : compose previous code chunks
    def compose(self):
        # TODO:70 replace placeholder on complexities by input/filtering/sink/exec_queries
        # temporary code
        self.current_code = ""
        self.current_code += str(self.current_input.code)
        self.current_code += str(self.current_filtering.code)
        self.current_code += str(self.current_sink.code)
        if self.current_exec_queries:
            self.current_code += str(self.current_exec_queries.code)
        self.write_files()

    # eighth step : write on disk and update manifest
    def write_files(self):
        # TODO:80 write on file
        filename = self.generate_file_name()
        print(filename)
        print("#########################################")
        print("safe : "+str(self.is_safe_selection()))
        print(self.current_code)
        print("#########################################")
        # TODO:60 update Manifest
        # self.manifest.addFileToTestCase(self.current_sink.flaw_group)

    def set_flaw_type_user(self, value):
        self.flaw_type_user = value

    def set_flaw_group_user(self, value):
        self.flaw_group_user = value

    def generate_file_name(self):
        # CWE input filtering sink [exec] complexity
        name = self.current_sink.flaw_type
        name += "__"
        name += self.current_input.generate_file_name()
        name += "__"
        name += self.current_filtering.generate_file_name()
        name += "__"
        name += self.current_sink.generate_file_name()
        name += "."+self.main_class.file_extension

        if self.current_exec_queries is not None:
            name += "__"
            name += self.exec_query.type

        # TODO add complexity
        return name

    # TODO:20 move this elsewhere either in the generator either in a new class
    def onDestroy(self, flaw):
        self.manifest.close()
        if self.safe_Sample+self.unsafe_Sample > 0:
            print(flaw + " generation report:")
            print(str(self.safe_Sample) + " safe samples")
            print(str(self.unsafe_Sample) + " unsafe samples")
            print(str(self.unsafe_Sample + self.safe_Sample) + " total\n")
        else:
            shutil.rmtree("../CsharpTestSuite_"+self.date+"/"+flaw)

    @staticmethod
    def findFlaw(fileName):
        sample = open(fileName, 'r')
        i = 0
        for line in sample.readlines():
            i += 1
            if line[:6] == "//flaw":
                break
        return i + 1
<commit_msg>refactor Generator<commit_after>import shutil
from Classes.Manifest import Manifest
from .Input import InputSample
from .Filtering import FilteringSample
from .Sink import SinkSample
from .ExecQuery import ExecQuerySample
from .Complexity import ComplexitySample
from .MainClass import MainClassSample
from Classes.FileManager import FileManager
import xml.etree.ElementTree as ET

class Generator():

    MAX_RECURSION = 1
    # HACK  >=0 : generate NUMBER_GENERATE of trio (input,filtering,sink) , -1 : unlimited
    NUMBER_GENERATE = -1

    def __init__(self, date):
        self.date = date
        # TODO:60 readd this for manifest generation
        # self.manifest = Manifest(date, flaw)
        self.safe_Sample = 0
        self.unsafe_Sample = 0
        self.flaw_type_user = None
        self.flaw_group_user = None

        # parse XML files
        tree_input = ET.parse(FileManager.getXML("input")).getroot()
        self.tab_input = [InputSample(inp) for inp in tree_input]
        tree_filtering = ET.parse(FileManager.getXML("filtering")).getroot()
        self.tab_filtering = [FilteringSample(filtering) for filtering in tree_filtering]
        tree_sink = ET.parse(FileManager.getXML("sink")).getroot()
        self.tab_sink = [SinkSample(sink) for sink in tree_sink]
        tree_exec_query = ET.parse(FileManager.getXML("exec_queries")).getroot()
        self.tab_exec_queries = [ExecQuerySample(exec_query) for exec_query in tree_exec_query]
        tree_complexities = ET.parse(FileManager.getXML("complexities")).getroot()
        self.tab_complexity = [ComplexitySample(complexity) for complexity in tree_complexities.find("complexities")]
        self.main_class = MainClassSample(ET.parse(FileManager.getXML("main_class")).getroot())

        # set current samples
        self.current_input = None
        self.current_filtering = None
        self.current_sink = None
        self.current_exec_queries = None
        self.current_code = None
        # HACK
        self.number_generate = Generator.NUMBER_GENERATE

    def generate(self):
        self.select_sink()

    # fist step : browse sink
    def select_sink(self):
        for sink in self.tab_sink:
            if ((not self.flaw_type_user or sink.flaw_type_number() in self.flaw_type_user)
               and (not self.flaw_group_user or sink.flaw_group in self.flaw_group_user)):
                self.current_sink = sink
                self.select_filtering()

    # second step : browse filtering
    def select_filtering(self):
        # select filtering
        for filtering in self.tab_filtering:
            self.current_filtering = filtering
            # check if sink and filtering are compatibles
            if filtering.compatible_with_sink(self.current_sink):
                self.select_input()

    # third step : browse input
    def select_input(self):
        # select input
        for inp in self.tab_input:
            if inp.compatible_with_filtering_sink(self.current_filtering, self.current_sink):
                self.current_input = inp
                self.recursion_level()

    # fouth step : compute recursion level
    def recursion_level(self):
        # HACK
        if self.number_generate == 0:
            return
        self.number_generate -= 1

        # generate with 0,1,2,... level of complexities
        for i in range(0, Generator.MAX_RECURSION+1):
            self.select_complexities(i)

    # fourth step bis : browse complexities
    def select_complexities(self, level):
        print(level)
        if level == 0:
            self.select_exec_queries()
        else:
            # Select complexity for this level
            for complexity in self.tab_complexity:
                self.select_complexities(level-1)

    # fifth step : browse exec_queries
    def select_exec_queries(self):
        if self.current_sink.need_exec():
            # select exec_queries
            for exec_query in self.tab_exec_queries:
                if self.current_sink.compatible_with_exec_queries(exec_query):
                    self.current_exec_queries = exec_query
                    self.compose()
        else:
            self.current_exec_queries = None
            self.compose()

    # seventh step : compose previous code chunks
    def compose(self):
        # TODO:70 replace placeholder on complexities by input/filtering/sink/exec_queries
        # TODO fill template with code chunks
        # temporary code
        self.current_code = ""
        self.current_code += str(self.current_input.code)
        self.current_code += str(self.current_filtering.code)
        self.current_code += str(self.current_sink.code)
        if self.current_exec_queries:
            self.current_code += str(self.current_exec_queries.code)

        self.write_files()

    # eighth step : write on disk and update manifest
    def write_files(self):
        # TODO:80 write on file
        filename = self.generate_file_name()
        print(filename)
        print("#########################################")
        print("safe : "+str(self.is_safe_selection()))
        print(self.current_code)
        print("#########################################")
        # TODO:60 update Manifest
        # self.manifest.addFileToTestCase(self.current_sink.flaw_group)

    def get_group_list(self):
        return {sink.flaw_group.upper() for sink in self.tab_sink}

    def get_cwe_list(self):
        return {sink.flaw_type_number() for sink in self.tab_sink}

    def is_safe_selection(self):
        return (self.current_input.is_safe(self.current_sink.flaw_type)
                or self.current_filtering.is_safe(self.current_sink.flaw_type) or
                self.current_sink.safe)

    def set_flaw_type_user(self, value):
        self.flaw_type_user = value

    def set_flaw_group_user(self, value):
        self.flaw_group_user = value

    def generate_file_name(self):
        # CWE input filtering sink [exec] complexity
        name = self.current_sink.flaw_type
        name += "__"
        name += self.current_input.generate_file_name()
        name += "__"
        name += self.current_filtering.generate_file_name()
        name += "__"
        name += self.current_sink.generate_file_name()

        if self.current_exec_queries is not None:
            name += "__"
            name += self.exec_query.type

        # TODO add complexity

        # extension
        name += "."+self.main_class.file_extension
        return name

    # TODO:20 move this elsewhere either in the generator either in a new class
    def onDestroy(self, flaw):
        self.manifest.close()
        if self.safe_Sample+self.unsafe_Sample > 0:
            print(flaw + " generation report:")
            print(str(self.safe_Sample) + " safe samples")
            print(str(self.unsafe_Sample) + " unsafe samples")
            print(str(self.unsafe_Sample + self.safe_Sample) + " total\n")
        else:
            shutil.rmtree("../CsharpTestSuite_"+self.date+"/"+flaw)

    @staticmethod
    def findFlaw(fileName):
        sample = open(fileName, 'r')
        i = 0
        for line in sample.readlines():
            i += 1
            if line[:6] == "//flaw":
                break
        return i + 1
<|endoftext|>