22
26
AttemptToContributeToNonExportedInterface,
23
27
ConflictInContributingInterfaces, find_interfaces_and_contributors)
24
28
from lazr.restful._resource import EntryAdapterUtility, EntryResource
25
from lazr.restful.testing.webservice import FakeRequest
29
from lazr.restful.testing.webservice import (
31
TestCaseWithWebServiceFixtures,
26
33
from lazr.restful.testing.helpers import (
27
34
create_test_module, TestWebServiceConfiguration, register_test_module)
30
class ContributingInterfacesTestCase(unittest.TestCase):
37
class ContributingInterfacesTestCase(TestCaseWithWebServiceFixtures):
31
38
"""Tests for interfaces that contribute fields/operations to others."""
35
TestWebServiceConfiguration(), IWebServiceConfiguration)
41
super(ContributingInterfacesTestCase, self).setUp()
36
42
sm = getSiteManager()
38
ITestServiceRequestBeta, IWebServiceVersion, name='beta')
40
ITestServiceRequest10, IWebServiceVersion, name='1.0')
41
43
sm.registerAdapter(ProductToHasBugsAdapter)
42
44
sm.registerAdapter(ProjectToHasBugsAdapter)
43
45
sm.registerAdapter(ProductToHasBranchesAdapter)
44
46
sm.registerAdapter(DummyFieldMarshaller)
45
self.beta_request = FakeRequest(version='beta')
47
self.beta_request, getUtility(IWebServiceVersion, name='beta'))
48
47
self.one_zero_request = FakeRequest(version='1.0')
50
49
self.one_zero_request, getUtility(IWebServiceVersion, name='1.0'))
50
self.two_zero_request = FakeRequest(version='2.0')
52
self.two_zero_request, getUtility(IWebServiceVersion, name='2.0'))
51
53
self.product = Product()
52
54
self.project = Project()
68
70
self.product._bug_count = 10
69
71
register_test_module('testmod', IProduct, IHasBugs)
70
72
adapter = getMultiAdapter(
71
(self.product, self.beta_request),
73
(self.product, self.one_zero_request),
72
74
IResourceGETOperation, name='getBugsCount')
73
75
self.assertEqual(adapter(), '10')
75
77
def test_contributing_interface_with_differences_between_versions(self):
76
# In the 'beta' version, IHasBranches.development_branches is exported
77
# with its original name whereas for the '1.0' version it's exported
78
# as 'development_branch_10'.
78
# In the '1.0' version, IHasBranches.development_branches is exported
79
# with its original name whereas for the '2.0' version it's exported
80
# as 'development_branch_20'.
79
81
self.product._dev_branch = Branch('A product branch')
80
82
register_test_module('testmod', IProduct, IHasBranches)
81
adapter = getMultiAdapter((self.product, self.beta_request), IEntry)
83
adapter = getMultiAdapter((self.product, self.one_zero_request), IEntry)
82
84
self.assertEqual(adapter.development_branch, self.product._dev_branch)
84
86
adapter = getMultiAdapter(
85
(self.product, self.one_zero_request), IEntry)
87
(self.product, self.two_zero_request), IEntry)
87
adapter.development_branch_10, self.product._dev_branch)
89
adapter.development_branch_20, self.product._dev_branch)
89
91
def test_mutator_for_just_one_version(self):
90
# On the 'beta' version, IHasBranches contributes a read only
91
# development_branch field, but on version '1.0' that field can be
92
# On the '1.0' version, IHasBranches contributes a read only
93
# development_branch field, but on version '2.0' that field can be
92
94
# modified as we define a mutator for it.
93
95
self.product._dev_branch = Branch('A product branch')
94
96
register_test_module('testmod', IProduct, IHasBranches)
95
adapter = getMultiAdapter((self.product, self.beta_request), IEntry)
97
adapter = getMultiAdapter((self.product, self.one_zero_request), IEntry)
97
99
adapter.development_branch = None
98
100
except AttributeError:
101
103
self.fail('IHasBranches.development_branch should be read-only '
102
'on the beta version')
104
'on the 1.0 version')
104
106
adapter = getMultiAdapter(
105
(self.product, self.one_zero_request), IEntry)
107
adapter.development_branch_10, self.product._dev_branch)
108
adapter.development_branch_10 = None
110
adapter.development_branch_10, None)
107
(self.product, self.two_zero_request), IEntry)
109
adapter.development_branch_20, self.product._dev_branch)
110
adapter.development_branch_20 = None
112
adapter.development_branch_20, None)
112
114
def test_contributing_to_multiple_interfaces(self):
113
115
# Check that the webservice adapter for both IProduct and IProject
342
344
adapts(Interface, IHTTPRequest)
345
class ITestServiceRequestBeta(IWebServiceVersion):
347
class ITestServiceRequest10(IWebServiceVersion):
347
# Classes for TestReqireExplicitVersions
349
class IFieldExportedWithoutAsOf(Interface):
350
export_as_webservice_entry()
352
field = exported(TextLine(), exported=True)
355
class IFieldExportedToEarliestVersionUsingAsOf(Interface):
356
export_as_webservice_entry()
358
field = exported(TextLine(), as_of='1.0')
361
class IFieldExportedToLatestVersionUsingAsOf(Interface):
362
export_as_webservice_entry()
364
field = exported(TextLine(), as_of='2.0')
367
class IFieldDefiningAttributesBeforeAsOf(Interface):
368
export_as_webservice_entry()
370
field = exported(TextLine(), ('1.0', dict(exported=True)),
373
class IFieldAsOfNonexistentVersion(Interface):
374
export_as_webservice_entry()
376
field = exported(TextLine(), as_of='nosuchversion')
379
class IFieldDoubleDefinition(Interface):
380
export_as_webservice_entry()
382
field = exported(TextLine(), ('2.0', dict(exported_as='name2')),
383
exported_as='name2', as_of='2.0')
386
class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures):
387
"""Test behavior when require_explicit_versions is True."""
390
super(TestRequireExplicitVersions, self).setUp()
391
self.utility = getUtility(IWebServiceConfiguration)
392
self.utility.require_explicit_versions = True
394
def _assertRaises(self, exception, func, *args, **kwargs):
395
# Approximate the behavior of testtools assertRaises, which
396
# returns the raised exception. I couldn't get
397
# testtools.TestCase to play nicely with zope's Cleanup class.
398
self.assertRaises(exception, func, *args, **kwargs)
400
func(*args, **kwargs)
404
def test_field_exported_as_of_earlier_version_is_exported_in_subsequent_versions(self):
405
# If you export a field as_of version 1.0, it's present in
406
# 1.0's version of the entry and in all subsequent versions.
407
interfaces = generate_entry_interfaces(
408
IFieldExportedToEarliestVersionUsingAsOf, [],
409
*self.utility.active_versions)
410
interface_10 = interfaces[0][1]
411
interface_20 = interfaces[1][1]
412
self.assertEquals(interface_10.names(), ['field'])
413
self.assertEquals(interface_20.names(), ['field'])
415
def test_field_exported_as_of_later_version_is_not_exported_in_earlier_versions(self):
416
# If you export a field as_of version 2.0, it's not present in
417
# 1.0's version of the entry.
418
interfaces = generate_entry_interfaces(
419
IFieldExportedToLatestVersionUsingAsOf, [],
420
*self.utility.active_versions)
421
interface_10 = interfaces[0][1]
422
interface_20 = interfaces[1][1]
423
self.assertEquals(interface_10.names(), [])
424
self.assertEquals(interface_20.names(), ['field'])
426
def test_field_not_exported_using_as_of_fails(self):
427
# If you export a field without specifying as_of, you get an
429
exception = self._assertRaises(
430
ValueError, generate_entry_interfaces,
431
IFieldExportedWithoutAsOf, [], *self.utility.active_versions)
434
('Field "field" in interface "IFieldExportedWithoutAsOf": '
435
'Field was exported in version 1.0, but not by using as_of. '
436
'The service configuration requires that you use as_of.')
439
def test_field_cannot_be_both_exported_and_not_exported(self):
440
# If you use the as_of keyword argument, you can't also set
441
# the exported keyword argument to False.
442
exception = self._assertRaises(
443
ValueError, exported, TextLine(), as_of='1.0', exported=False)
446
('as_of=1.0 says to export TextLine, but exported=False '
449
def test_field_exported_as_of_nonexistent_version_fails(self):
450
# You can't export a field as_of a nonexistent version.
451
exception = self._assertRaises(
452
ValueError, generate_entry_interfaces,
453
IFieldAsOfNonexistentVersion, [],
454
*self.utility.active_versions)
457
('Field "field" in interface "IFieldAsOfNonexistentVersion": '
458
'Unrecognized version "nosuchversion".'))
460
def test_field_exported_with_duplicate_attributes_fails(self):
461
# You can't provide a dictionary of attributes for the
462
# version specified in as_of.
463
exception = self._assertRaises(
464
ValueError, generate_entry_interfaces,
465
IFieldDoubleDefinition, [], *self.utility.active_versions)
468
('Field "field" in interface "IFieldDoubleDefinition": '
469
'Duplicate annotations for version "2.0".'))
471
def test_field_with_annotations_that_precede_as_of_fails(self):
472
# You can't provide a dictionary of attributes for a version
473
# preceding the version specified in as_of.
474
exception = self._assertRaises(
475
ValueError, generate_entry_interfaces,
476
IFieldDefiningAttributesBeforeAsOf, [],
477
*self.utility.active_versions)
480
('Field "field" in interface '
481
'"IFieldDefiningAttributesBeforeAsOf": Version "1.0" defined '
482
'after the later version "2.0".'))