# -*- test-case-name: mv3d.test.test_editor -*- # Copyright (C) 2006-2012 Mortal Coil Games # See LICENSE for details. """ """ from twisted.trial.unittest import TestCase from twisted.internet import defer from twisted.internet.defer import inlineCallbacks from zope.interface import implements from nevow import tags as T, inevow from mv3d.net.client import ServiceLoc try: from mv3d.client.ui.editor import TopLevelEditor, BoxCreatorView, Factory noOgre = "" except ImportError: noOgre = "Ogre is not available." from mv3d.server.editor import ( makeFriendlyURL, setIdList, getEditableSections, getPageOffsetLimit, MainNav, SubNav, WebEditMixin, WebEditSection, WebEditModifier, AccessDenied, WebRoot, Stats, ViewAssetGroups, WebEditTarget, notEditable, textBox, List, EditPermissions, PermissionModifier, Permission, ViewAccounts, AssetGroupEditor, unfoldServiceList, setServiceList, ViewDirectories, DeleteAssetGroup, DeleteAsset) from mv3d.util.modifier import IModifiable from mv3d.test.mixins import WithDocTests from mv3d.test.ui.test_layout import WithFakeUI from mv3d.util.conductor import IConductor class FakeConductor: """ A fake conductor """ implements(IConductor) def __init__(self): self.camera = self def getOneService(self, lst): return defer.succeed(self) def getPCInfo(self, pc): return defer.succeed([pc, pc, pc]) def getLocalService(self, _typ): """ return it """ return self def getUI(self): """ return self """ return self def getDefaultInputContext(self): """ return self """ return self def newInputContext(self, _nm, active): """ return self """ return self def registerMouseCallback(self, _): """ do nothing """ def registerKeyCallback(self, _, __, ___): """ do nothing """ def stop(self): """ do nothing """ def getRenderer(self): """ return self """ return self class FakePlayerClient: """ A fake client """ def __init__(self): self.parent = FakeConductor() self.loginservers = [ServiceLoc("pb://1.2.3.4/hi")] def getPCs(self): return defer.succeed([(0, 1), (0, 2)]) def connectPC(self, pcid): return defer.succeed(25) def createCharacter(self): self.deferred = defer.Deferred() return self.deferred def do(self, what, *a, **kw): return defer.succeed({"george":{"one":1}}) class FakeUI: """ A fake uI class """ def __init__(self): self.log = [] self.client = FakePlayerClient() self.renderer = self self.camera = self self.guideWidget = self self.renderWindow = self self._cam = self self._node = self self.keyListeners = [] self.mouseListeners = [] self.fcbs = [] def createComponent(self, *a, **kw): self.log.append(("createComponent", a, kw)) return FakeComponent() def getComponent(self, nm): self.log.append(("getComponent", nm)) # return FakeComponent() raise RuntimeError("Hello") def loadLayout(self, nm, p): self.log.append(("loadLayout", nm, p)) return FakeComponent() def displayWindow(self, nm): self.log.append(("displayWindow", nm)) def hideWindow(self, nm): self.log.append(("hideWindow", nm)) def requestUICallback(self, *a): self.log.append(("requestUICallback", a)) return 23 def stopUICallback(self, *a): self.log.append(("stopUICallback", a)) def addRowToListBox(self, *a, **kw): self.log.append(("addRowToListBox", a, kw)) return 12 def addItemToComboBox(self, box, itm): """ Oddly enough, this does something different than the addRowToListBox """ self.log.append(("addItemToComboBox", box, itm)) return 24 def addFrameCallback(self, f, *a, **kw): """ Add a frame callback """ self.fcbs.append((f, a, kw)) def remFrameCallback(self, f, *a, **kw): """ Remove a frame callback """ try: self.fcbs.remove((f, a, kw)) except ValueError: pass def addKeyListener(self, func): """ Add a key listener """ self.keyListeners.append(func) def removeKeyListener(self, func): """ Remove a key listener """ self.keyListeners.remove(func) def addMouseListener(self, func): """ Add a mouse listener """ self.mouseListeners.append(func) def removeMouseListener(self, func): """ Remove a mouse listener """ self.mouseListeners.remove(func) def registerForRawMouseEvents(self, func): """ Do nothing """ def unregisterForRawMouseEvents(self, func): """ Do nothing """ def registerForRawKeyboardEvents(self, func): """ Do nothing """ def unregisterForRawKeyboardEvents(self, func): """ DO nothing """ def setNearClip(self, distance): """ Ignored """ def setFarClip(self, distance): """ Ignored """ def pause(self): """ Do nothing """ def setupCamera(self, camera): """ Do nothing """ class FakeComponent: """ The fake component class """ def __init__(self): self.log = [] def addColumn(self, *a, **kw): self.log.append(("addColumn", a, kw)) def resetList(self): self.log.append("resetList") def getFirstSelectedItem(self): class FakeSel: def __init__(self): self.text = self def c_str(self): return "(1,23)" return FakeSel() def addChildWindow(self, win): self.log.append(("addChildWindow", win)) def getText(self): return self text = property(getText) def c_str(self): return "0:jane" class FakeRemoteRef: """ A fake RemoteReference """ def callRemote(self, f, *a, **kw): return defer.maybeDeferred(getattr(self, f), *a, **kw) def getUI(self): return self def construct(self, ui, editor): self.ui = ui self.editor = editor self.constructed = True return defer.succeed(self) def start(self): self.started = True class TopLevelEditorTests(TestCase, WithDocTests): """ Test the top level editor UI """ if noOgre: skip = noOgre def assertLogQuick(self, log, expect): """ Just check that the first element in the log is correct """ nlog = map(lambda x: x[0], log) self.assertEqual(nlog, expect) def test_docs(self): """ Test all the docstrings """ self.checkDocs(TopLevelEditor) def test_initialize(self): """ Test initializing the TopLevelEditor """ tle = TopLevelEditor(FakeUI(), FakePlayerClient()) tle.initialize() self.assertLogQuick(tle.ui.log, [ 'createComponent', 'createComponent', 'createComponent', 'createComponent']) def test_createSubwindow(self): """ Test creating a sub window """ tle = TopLevelEditor(FakeUI(), FakePlayerClient()) tle.ui = FakeUI() tle.editors = dict(spam={"hello":12}) tle.subWindows = {} tle.subButtons = {} m = tle.createSubwindow("spam") self.assertLogQuick(tle.ui.log, [ 'createComponent', 'createComponent']) def test_subButtonClicked(self): """ Test the results of clicking on a sub button """ tle = TopLevelEditor(FakeUI(), FakePlayerClient()) tle.ui = 123 frr = FakeRemoteRef() tle.editors = dict(spam={"hello":frr}) tle.subButtonClicked("spam", "hello") self.assertEqual(frr.constructed, True) self.assertEqual(frr.ui, tle.ui) self.assertEqual(frr.editor, frr) self.assertEqual(frr.started, True) def test_start(self): """ Test that starting the UI works """ tle = TopLevelEditor(FakeUI(), FakePlayerClient()) tle.editors = dict(spam={"hello":12}) tle.initialize() tle.start() self.assertLogQuick(tle.ui.log, [ 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'displayWindow', 'requestUICallback', 'requestUICallback']) class BoxCreatorViewTests(TestCase, WithDocTests): """ Test the BoxCreatorView """ if noOgre: skip = noOgre def assertLogQuick(self, log, expect): """ Just check that the first element in the log is correct """ nlog = map(lambda x: x[0], log) self.assertEqual(nlog, expect) def test_docs(self): """ Test all the docstrings """ self.checkDocs(BoxCreatorView) def test_initialize(self): """ Test initializing the UI """ bev = BoxCreatorView(FakeUI(), None) self.assertLogQuick(bev.ui.log, [ 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'createComponent', 'requestUICallback', 'requestUICallback']) class FakeModifiable: implements(IModifiable, IConductor) modifiers = None def __init__(self, good, services=None, name=None): self.good = good self.services = services self.name = name def checkPermissions(self, user, perm): if user in self.good: return True return False def getModifiers(self, type, conductor=None): return defer.succeed(self.modifiers) class ServiceLocHolder: def __init__(self, locs): self.locs = [ServiceLoc(loc) for loc in locs] def getLocs(self): return self.locs def setLocs(self, locs): self.locs = locs class WebEditorMiscTests(TestCase): """ Test some global functions in editor.py """ def test_makeFriendlyURL(self): """ Run a bunch of tests against makeFriendlyURL and check for correct results """ tests = [("testthislongline", "testthislongline"), ("line with spaces", "line_with_spaces"), ("line32", "line32"), ("line+!@#$%^&*()-+~`{}[]\\|;:'\",<.>/?", "line/"), ] for test, result in tests: self.assertEqual(makeFriendlyURL(test), result) def test_setIdList(self): """ Test the setIdList function """ tests = [("(1,2)", [(1, 2)]), ("(1,2),(3,4)", [(1, 2), (3, 4)]), ("(1,2), (3,4)", [(1, 2), (3, 4)]), ("(1,2) , (3,4)", [(1, 2), (3, 4)]), (" ( 1 , 2 ) , ( 3 , 4 ) ", [(1, 2), (3, 4)]), ("(3,2), (4,5), (8,9)", [(3, 2), (4, 5), (8, 9)]), ("", []), (" ", []), (",", []), ("(3,2),", [(3, 2)]), ] results = [] class IdTester: def george(self, y): results.append(y) f = setIdList("george") idt = IdTester() for test, result in tests: f(idt, test) self.assertEqual(results[ -1], result) def test_getEditableSections(self): """ Test the getEditableSections function """ m = FakeModifiable(["mike"], [FakeModifiable(["mike"])]) r = getEditableSections(m, "mike") self.assertEqual(len(r), 2) r = getEditableSections(m, "larry") self.assertEqual(len(r), 0) def test_getPageOffsetLimit(self): """ Test the getPageOffsetLimit function """ tests = [(5, 2, 5, 5), (20, 1, 0, 20), (11, 11, 110, 11)] for pagesz, page, offset, limit in tests: self.assertEqual( getPageOffsetLimit(pagesz, page), (offset, limit)) def test_unfoldServiceList(self): """ Test the unfoldServiceList function """ slho = ServiceLocHolder(["pb://localhost"]) result = unfoldServiceList("lst", slho.locs) self.assertEqual(repr(result), "Tag('input', attributes={'type': 'text', 'name': 'lst', 'value':" " 'pb://localhost'})") def test_unfoldServiceListEmpty(self): """ Test the unfoldServiceList function with an empty list """ result = unfoldServiceList("me", []) self.assertEqual(repr(result), "Tag('input', attributes={'type': 'text'," " 'name': 'me', 'value': ''})") def test_unfoldServiceListMulti(self): """ Test the unfoldServiceList function with multiple items """ slho = ServiceLocHolder(["http://localhost", "pb://mars/george"]) result = unfoldServiceList("hop", slho.locs) self.assertEqual(repr(result), "Tag('input', attributes={'type': 'text', 'name': 'hop', 'value':" " 'http://localhost, pb://mars/george'})") def test_setServiceList(self): """ Test setServiceList """ slho = ServiceLocHolder(["http://localhost", "pb://mars/george"]) setServiceList("setLocs")(slho, "pb://mv3d.com") self.assertEqual(len(slho.locs), 1) self.assertEqual(slho.locs[0].toString(), "pb://mv3d.com") def test_setServiceListEmpty(self): """ Test setServiceList """ slho = ServiceLocHolder(["http://localhost", "pb://mars/george"]) setServiceList("setLocs")(slho, "") self.assertEqual(len(slho.locs), 0) def test_setServiceListMulti(self): """ Test setServiceList """ slho = ServiceLocHolder(["http://localhost", "pb://mars/george"]) setServiceList("setLocs")(slho, "pb://mv3d.com,http://good.com, self://ash ") self.assertEqual(len(slho.locs), 3) self.assertEqual(slho.locs[0].toString(), "pb://mv3d.com") self.assertEqual(slho.locs[1].toString(), "http://good.com") self.assertEqual(slho.locs[2].toString(), "self://ash") class FakeParent: """ Fake parent """ implements(IConductor) def __init__(self): self.parent = self def getServiceNamed(self, name): """ Return self """ return self def checkPermissions(self, _perm, _who): """ return true """ return True class FakeModifier: """ A fake modifier """ name = "Fake Mod" shortName = "fmod" templateDir = None def setDocFactory(self, dir_): """ set it """ self.templateDir = dir_ def childFactory(self, _ctx, name): """ return name """ return name def getMinimumPermissions(self): """ return stuff""" return ["read", "modify"] class FakeRoot: """ Root faker """ location = "test" client = "willow" templateDir = "/boo/" def __init__(self): self.parent = FakeParent() self.modifiers = dict(flowers=[FakeModifier()], boo=[]) def getAllTopModifiers(self): return defer.succeed(self.modifiers) def getServiceNamed(self, name): return name class MainNavTests(TestCase, WithDocTests): """ Test the MainNav class """ def setUp(self): self.root = FakeRoot() self.mnav = MainNav(self.root, "flowers") def test_docs(self): """ Test all the docstrings """ self.checkDocs(MainNav) def test_generateSectionLink(self): """ Test the generateSectionLink method """ tests = [("magic", "Tag('a', attributes={'href': '/test/magic'}, children=['magic'])")] for section, result in tests: r = self.mnav.generateSectionLink(section) self.assertEqual(str(r), result) def test_dataSections(self): """ Test getting the sections """ m = FakeModifiable(["willow"], [FakeModifiable(["willow"], None, "test2")], "test1") self.mnav.parent.parent = m self.mnav.sections = "YO" self.assertEqual(self.mnav.data_sections(None, None), "YO") self.mnav.sections = None self.assertEqual(str(self.mnav.data_sections(None, None)), "[Tag('a', attributes={'href': '/test/test1'}, children=['test1']), " "Tag('a', attributes={'href': '/test/test2'}, children=['test2'])]") class SubNavTests(TestCase, WithDocTests): """ Test the SubNav class """ def setUp(self): self.root = FakeRoot() self.snav = SubNav(self.root, "flowers") def test_docs(self): """ Test all the docstrings """ self.checkDocs(SubNav) def test_generateModifierLink(self): """ Test the generateModifierLink method """ tests = [(FakeModifier(), "Tag('a', attributes={'href': '/test/flowers/fmod'}, " "children=['Fake Mod'])")] for section, result in tests: r = self.snav.generateModifierLink(section) self.assertEqual(str(r), result) @inlineCallbacks def test_dataModifiers(self): """ Test the data_modifiers function """ self.snav.modifiers = "HI" self.assertEqual(self.snav.data_modifiers(None, None), "HI") self.snav.modifiers = None r = yield self.snav.data_modifiers(None, None) self.assertEqual(str(r), "[Tag('a', attributes={'href': '/test/flowers/fmod'}, " "children=['Fake Mod'])]") class DeferredChildFactory(WebEditMixin): """ this child factory always returns a deferred """ def childFactory(self, ctx, name): return defer.succeed(name) class NotDeferredChildFactory(WebEditMixin): """ this child factory never returns a deferred """ def childFactory(self, ctx, name): return name class WebEditMixinTests(TestCase, WithDocTests): """ Test the WebEditMixin class """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(WebEditMixin) @inlineCallbacks def test_deferredLocateChild(self): """ Test using a deferred returning childFactory with locateChild """ dcf = DeferredChildFactory() r = yield dcf.locateChild(None, ["george", "fred"]) self.assertEqual(r, ("george", ["fred"])) ndcf = NotDeferredChildFactory() r = yield dcf.locateChild(None, ["frank", "harry"]) self.assertEqual(r, ("frank", ["harry"])) class WebEditSectionTests(TestCase, WithDocTests): """ Test the WebEditSection class """ def setUp(self): self.root = FakeRoot() self.wes = WebEditSection(self.root, "flowers") def test_docs(self): """ Test all the docstrings """ self.checkDocs(WebEditSection) @inlineCallbacks def test_getEditPane(self): """ Test getting the edit pane """ r = yield self.wes.getEditPane() self.assertIdentical(r, self.root.modifiers["flowers"][0]) self.assertEqual(r.templateDir, "/boo/") self.wes.section = "harry" r = yield self.wes.getEditPane() self.assertEqual(r, "") self.wes.section = "boo" r = yield self.wes.getEditPane() self.assertEqual(r, "") @inlineCallbacks def test_childFactory(self): """ Test the childFactory of WebEditSection """ self.root.parent.parent = self.root r = yield self.wes.childFactory(None, "fmod") self.assertEqual(r.root, self.root) self.assertEqual(r.modifierName, "Fake Mod") self.wes.section = "harry" r = yield self.wes.childFactory(None, "fmod") self.assertEqual(r, None) self.wes.section = "boo" r = yield self.wes.childFactory(None, "fmod") self.assertEqual(r, None) class WebEditModifierTests(TestCase, WithDocTests): """ Test the WebEditModifier class """ def setUp(self): self.root = FakeRoot() self.target = FakeModifiable(["willow"]) self.target.modifiers = [FakeModifier()] self.wem = WebEditModifier(self.root, "flowers", self.target, "george") def test_docs(self): """ Test all the docstrings """ self.checkDocs(WebEditModifier) @inlineCallbacks def test_getEditPane(self): """ Test getting the edit pane """ r = yield self.wem.getEditPane() self.assertEqual(len(r), 4) self.assertEqual(r[0], "Available modifiers for ") self.wem.modifierName = "Fake Mod" r = yield self.wem.getEditPane() self.assertEqual(r.name, "Fake Mod") self.root.client = dict(username="george") r = yield self.wem.getEditPane() self.assertIsInstance(r, AccessDenied) @inlineCallbacks def test_childFactory(self): """ Test the childFactory of WebEditModifier """ self.wem.modifierName = "Fake Mod" self.root.client = dict(username="hi") self.target.good = [self.root.client] r = yield self.wem.childFactory(None, "fred") self.assertEqual(r, "fred") self.wem.modifierName = None r = yield self.wem.childFactory(None, "fmod") self.assertEqual(r.modifierName, "Fake Mod") r = yield self.wem.childFactory(None, "ho") self.assertEqual(r, None) self.target.good = [] r = yield self.wem.childFactory(None, "fmod") self.assertIsInstance(r.editPane, AccessDenied) class WebRootTests(TestCase, WithDocTests): """ Test the WebRoot class """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(WebRoot) @inlineCallbacks def test_getAllTopModifiers(self): """ Test getting all the top level modifiers """ parent = FakeParent() parent.parent = FakeModifiable(["mike"], [FakeModifiable(["mike"], name="george")], "frank") parent.parent.modifiers = [FakeModifier()] parent.parent.services[0].modifiers = [FakeModifier()] root = WebRoot("mike", parent, "/") root.topMods = "hello" t = yield root.getAllTopModifiers() self.assertEqual(t, "hello") root.topMods = None t = yield root.getAllTopModifiers() self.assertEqual(t["frank"], parent.parent.modifiers) self.assertEqual(t["george"], parent.parent.services[0].modifiers) def test_noSections(self): """ Test initializing a WebRoot without sections. """ parent = FakeParent() parent.parent = FakeModifiable(["mike"], [], None) parent.parent.modifiers = [] root = WebRoot("george", parent, "/") self.assertIdentical(root.section, None) class StatGenerator: def __init__(self, stats): self.stats = stats def getStatistics(self): return self.stats class StatsTests(TestCase, WithDocTests): """ Test the Stats class """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(Stats) def test_dataStats(self): """ Test the stats data gatherer """ asg = Stats(StatGenerator({})) r = asg.data_stats(None, None) self.assertEqual(r, []) asg.target.stats = dict(one=123) r = asg.data_stats(None, None) self.assertEqual(r, [["one", 123]]) asg.target.stats = dict(one=123, two=234) r = asg.data_stats(None, None) self.assertEqual(r, [["two", 234, "one", 123]]) asg.target.stats = dict(one=123, two=234, three=345) r = asg.data_stats(None, None) self.assertEqual(r, [["three", 345, "two", 234], ["one", 123]]) class FakeAssetService: """ A fake asset service """ agid = 22 uid = 22 def __init__(self): self.parent = self self.group = self def getDirectoryServers(self): return 1 def getOneService(self, lst): return defer.succeed(self) def newMasterAssetGroup(self, typ): self.typ = typ return defer.succeed(1) def getAssetGroup(self, grp): return self def grantPermission(self, w, p): self.perms = (w, p) class TestItem: """ A test item for List testing """ one = 1 nun = None class ListTester(List): """ An object for testing the List """ def getLink(self, itm): return "linky" class ArgContext: """ A context object with args only """ implements(inevow.IRequest) def __init__(self, args): self.args = args self.tag = "you're it" self.log = [] def arg(self, name): return self.args.get(name) def redirect(self, loc): self.log.append(("redirect", loc)) class ListTests(TestCase, WithDocTests): """ Test the List Class """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(List) @inlineCallbacks def test_renderItemEmpty(self): """ Test rendering an item """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr')") @inlineCallbacks def test_renderItemSimple(self): """ Test rendering an item """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="one")] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td', children=[1])])") @inlineCallbacks def test_renderItemSubItem(self): """ Test rendering an item with subitems """ ti = TestItem() ti.two = TestItem() ti.two.three = 3 ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="two.three")] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td', children=[3])])") @inlineCallbacks def test_renderItemLink(self): """ Test rendering an item """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="one", link="/hi")] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td', children=" "[Tag('a', attributes={'href': 'linky/hi'}, children=[1])])])") @inlineCallbacks def test_renderItemNone(self): """ Test rendering an item """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="nun")] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td'," " children=['none'])])") @inlineCallbacks def test_renderItemWithDisplay(self): """ Test rendering an item """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="one", display=lambda d: d + 1)] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td', children=[2])])") @inlineCallbacks def test_renderItemWithDeferredDisplay(self): """ Test rendering an item with a deferred display func """ ti = TestItem() ti.name = "george" l = ListTester(None) l.attribs = [] ac = ArgContext({}) ac.tag = T.tr l.attribs = [dict(name="one", display=lambda d: defer.succeed(d + 1))] r = yield l.render_item(ac, ti) self.assertEqual(str(r), "Tag('tr', children=[Tag('td', children=[2])])") class ViewAssetGroupsTests(TestCase, WithDocTests): """ Tests for the ViewAssetGroups modifier """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(ViewAssetGroups) @inlineCallbacks def test_createNew(self): """ Test the createNew function """ root = FakeRoot() root.client = dict(username="mike") vag = ViewAssetGroups(FakeAssetService()) vag.root = root vag.section = "hi" root.location = "one" r = yield vag.createNew(ArgContext(dict(new="yes", classText="hi"))) self.assertEqual(str(r), "Tag('a', attributes={'href': '/one/hi/group/22/edit'}, " "children=['Created Asset Group 22'])") self.assertEqual(vag.target.typ.classname, "hi") self.assertEqual(vag.target.perms, ("all", "mike")) class TestDeleteAssetGroup(TestCase, WithDocTests): """ Tests for the DeleteAssetGroup modifier """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(DeleteAssetGroup) @inlineCallbacks def test_deleting(self): """ Regression for #990: Error deleting an asset group in the web editor. """ root = FakeRoot() root.client = dict(username="mike") dag = DeleteAssetGroup(FakeAssetGroup()) dag.root = root dag.section = "hi" root.location = "one" yield dag.render_checkPost(ArgContext(dict(yes=True)), None) self.failUnless(dag.target.deleted) class TestTarget: agid = 234 name = "steven" def setName(self, name): self.newname = name class MyWebEditTarget(WebEditTarget): attribs = [("agid", "ID:", notEditable, "setID"), ("name", "Name:", textBox, "setName")] def __init__(self): self.target = TestTarget() class FakeRequest: def __init__(self, args): self.args = args class WebEditTargetTests(TestCase, WithDocTests): """ Tests for the WebEditTarget class """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(WebEditTarget) def test_dataTarget(self): """ Test the data grabber for targets """ m = MyWebEditTarget() r = m.data_target(None, None) self.assertEqual(repr(r), "[['ID:', '234'], " "['Name:', Tag('input', attributes={'type': 'text', 'name': " "'name', 'value': 'steven'})]]") def test_setAttribs(self): """ Test the checkPost renderer """ m = MyWebEditTarget() req = FakeRequest(dict(agid=["2"], name=["dude"])) r = m.setAttribs(req) self.assertEqual(m.target.agid, 234) self.assertEqual(m.target.newname, "dude") class FakeSecurable: """ A fake security enabled object """ def __init__(self): self.allowedpermissions = ["read", "write", "arithmatic"] self.allowed = {} self.denied = {} self.log = [] def grantPermission(self, perm, who): plist = self.allowed.get(perm, []) plist.append(who) self.allowed[perm] = plist def denyPermission(self, perm, who): plist = self.denied.get(perm, []) plist.append(who) self.denied[perm] = plist def revokePermission(self, perm, who): self.log.append(("revoke", perm, who)) def remDeniedPermission(self, perm, who): self.log.append(("remDenied", perm, who)) def checkPermissions(self, who, perm): """ check it """ if who in self.allowed[perm] or "all" in self.allowed[perm]: return True return False class EditPermissionsTests(TestCase, WithDocTests): """ Test the permission editor """ def test_docs(self): """ Test all the docstrings """ self.checkDocs(EditPermissions) def test_getLink(self): """ Make sure that getLink raises an exception """ perm = EditPermissions(FakeSecurable()) perm.target.allowed = {"read":["me", "myself"]} self.assertEqual(perm.getLink(perm.generatePermissions()[0]), "./0") def test_getItemsBasic(self): """ Test that getItems returns a list of Permissions """ targ = FakeSecurable() perm = EditPermissions(targ) targ.allowed = {"read":["me", "myself"]} targ.denied = {"write":["you", "others"]} listy = perm.getItems(0, 100) self.assertEqual(len(listy), 4) self.assertEqual(listy[0].action, "grant") self.assertEqual(listy[0].permission, "read") self.assertEqual(listy[0].entity, "me") self.assertEqual(listy[3].action, "deny") self.assertEqual(listy[3].permission, "write") self.assertEqual(listy[3].entity, "others") def test_getItemsNoPerms(self): """ Test that getItems works when there are no permissions """ perm = EditPermissions(FakeSecurable()) self.assertEqual(perm.getItems(0, 100), []) def test_createNewGrant(self): """ Test creating a new permission """ fsec = FakeSecurable() fsec.grantPermission("modify", "willow") perm = EditPermissions(fsec) perm.root = FakeRoot() result = perm.createNew(ArgContext(dict(action="grant", permission="foo", entity="bar"))) self.assertEqual(perm.target.allowed["foo"], ["bar"]) def test_createNewDeny(self): """ Test creating a new denied permission """ fsec = FakeSecurable() fsec.grantPermission("modify", "willow") perm = EditPermissions(fsec) perm.root = FakeRoot() result = perm.createNew(ArgContext(dict(action="deny", permission="foo", entity="bar"))) self.assertEqual(perm.target.denied["foo"], ["bar"]) class PermissionModifierTest(TestCase, WithDocTests): """ Test the PermissionModifier class """ def test_docs(self): """ Check the docstrings """ self.checkDocs(PermissionModifier) def test_childFactory(self): """ Ensure that 'delete' is the only valid child. """ perm = PermissionModifier(FakeRoot(), 1, 2) self.assertRaises(ValueError, perm.childFactory, 1, "boo") self.assertEqual(perm.childFactory(1, "delete"), perm) def test_renderHTTPGrant(self): """ Test that renderHTTP deletes the item """ fsec = FakeSecurable() fsec.grantPermission("modify", "willow") perm = PermissionModifier(FakeRoot(), Permission("grant", "walk", "george"), fsec) ctx = ArgContext({}) perm.renderHTTP(ctx) self.assertEqual(perm.target.log, [('revoke', 'walk', 'george')]) self.assertEqual(ctx.log, [('redirect', '../')]) def test_renderHTTPDeny(self): """ Test that renderHTTP deletes the item """ fsec = FakeSecurable() fsec.grantPermission("modify", "willow") perm = PermissionModifier(FakeRoot(), Permission("deny", "walk", "george"), fsec) ctx = ArgContext({}) perm.renderHTTP(ctx) self.assertEqual(perm.target.log, [('remDenied', 'walk', 'george')]) self.assertEqual(ctx.log, [('redirect', '../')]) class FakeModifier2: """ Fake a modifier """ def __init__(self, shortName, name): self.name = name self.shortName = shortName class FakeAccount: """ Fake an account """ username = "fanko" def getModifiers(self, which, conductor=None): return defer.succeed([FakeModifier2("boo", "Boo boo"), FakeModifier2("hoo", "Hoo Hoo")]) class ViewAccountsTests(TestCase, WithDocTests): """ Test the ViewAccounts class """ def test_docs(self): """ Check the docstrings """ self.checkDocs(ViewAccounts) @inlineCallbacks def test_linkModifiers(self): """ Check the linkModifiers function """ vacct = ViewAccounts(123) vacct.root = FakeRoot() vacct.section = "hi" result = yield vacct.linkModifiers(FakeAccount()) self.assertEqual(repr(result), """[[Tag('li', children=[Tag('a', """ """attributes={'href': '/test/hi/account/fanko/boo'}, """ """children=['Boo boo'])])], [Tag('li', children=[Tag('a', """ """attributes={'href': '/test/hi/account/fanko/hoo'}, """ """children=['Hoo Hoo'])])]]""") def test_getLink(self): """ Test getting a link for an account """ vacct = ViewAccounts(123) vacct.root = FakeRoot() vacct.section = "hi" result = vacct.getLink(FakeAccount()) self.assertEqual(result, "/test/hi/account/fanko") class FakeAsset: """ Fake an asset """ deleted = False aid = 1, 1 def __init__(self): self.parent = self self.group = self def getAssetGroup(self, _agid): return self def remAsset(self, aid): assert aid == self.aid self.deleted = True class FakeAssetGroup: """ Fake an asset group """ deleted = False def __init__(self): self.assets = [FakeAsset(), FakeAsset(), FakeAsset(), FakeAsset()] self.cluster = self self.iddisp = self self.nextID = 4 self.parent = self self.agid = 1 def remAssetGroup(self, agid): assert self.agid == agid self.deleted = True return defer.succeed(None) class AssetGroupEditorTests(TestCase, WithDocTests): """ Test the AssetGroupEditor """ def test_docs(self): """ Check the docstrings """ self.checkDocs(AssetGroupEditor) def test_renderPageTurn(self): """ Make sure that rendering a pageturn works out ok """ aged = AssetGroupEditor(FakeAssetGroup()) ctx = ArgContext(dict(page=["1"])) ctx.tag = T.td() result = aged.render_pageTurn(ctx, 213) self.assertEqual(repr(result), """Tag('td', children=[Tag('td', """ """children=['']), Tag('td', attributes={'colspan': 5}, """ """children=[Tag('form', attributes={'method': 'POST', 'target': """ """'#page', 'name': 'pageturn'}, children=['page ', Tag('input', """ """attributes={'size': 3, 'class': 'text', 'value': '1', 'name': """ """'page'}), 'of 1'])]), Tag('td', children=[''])])""") def test_renderPageTurnTwoPages(self): """ Make sure that rendering a pageturn works out ok """ aged = AssetGroupEditor(FakeAssetGroup()) aged.perPage = 2 ctx = ArgContext(dict(page=["1"])) ctx.tag = T.td() result = aged.render_pageTurn(ctx, 213) self.assertEqual(repr(result), """Tag('td', children=[Tag('td', """ """children=['']), Tag('td', attributes={'colspan': 5}, """ """children=[Tag('form', attributes={'method': 'POST', 'target': """ """'#page', 'name': 'pageturn'}, children=['page ', Tag('input', """ """attributes={'size': 3, 'class': 'text', 'value': '1', 'name': """ """'page'}), 'of 2'])]), Tag('td', children=[Tag('a', """ """attributes={'href': '?page=2'}, children=['next'])])])""") def test_renderPageTurnTwoPagesSecondPage(self): """ Make sure that rendering a pageturn works out ok """ aged = AssetGroupEditor(FakeAssetGroup()) aged.perPage = 2 ctx = ArgContext(dict(page=["2"])) ctx.tag = T.td() result = aged.render_pageTurn(ctx, 213) self.assertEqual(repr(result), """Tag('td', children=[Tag('td', """ """children=[Tag('a', attributes={'href': '?page=1'}, """ """children=['previous'])]), Tag('td', attributes={'colspan': 5}""" """, children=[Tag('form', attributes={'method': 'POST', """ """'target': '#page', 'name': 'pageturn'}, children=['page ', """ """Tag('input', attributes={'size': 3, 'class': 'text', """ """'value': '2', 'name': 'page'}), 'of 2'])]), Tag('td', """ """children=[''])])""") class TestDeleteAsset(TestCase, WithDocTests): """ Test the AssetGroupEditor """ def test_docs(self): """ Check the docstrings """ self.checkDocs(DeleteAsset) @inlineCallbacks def test_deleteAsset(self): """ Regression for #991: Error deleting an asset in the web editor. """ root = FakeRoot() root.client = dict(username="mike") aged = DeleteAsset(FakeAsset()) aged.root = root aged.section = "hi" root.location = "one" yield aged.render_checkPost(ArgContext(dict(yes=True)), None) self.failUnless(aged.target.deleted) class FakeFactory: """ A faker """ def __init__(self): """ do nothing for now """ def callRemote(self, function, *args, **keys): """ return the local version """ return defer.succeed(getattr(self, function)(*args, **keys)) def getInputSections(self): """ Returns the list of input sections """ return dict( main=[ dict( type="Header", name="textey", text="This is a header", ), dict( type="String", name="title", label="Title:", value="initial value", ), dict( type="Position3D", name="position", value=(1, 2, 3) ), ], ) class FactoryTests(WithFakeUI, WithDocTests): """ Test the generic Factory client side UI """ if noOgre: skip = noOgre else: checkItems = (Factory,) @inlineCallbacks def test_build(self): """ Test building the Factory UI """ factory = Factory(self.ui, FakeFactory()) yield factory.build() myid = id(factory) self.assertEqual(factory.built, True) selid = id(factory.components.values()[0][-1]) self.assertLog([('create', 'WindowsLook/FrameWindow', 'Root/factory%d' % myid), ('create', 'WindowsLook/StaticText', 'factory%d/textey' % myid), ('create', 'WindowsLook/StaticText', 'factory%d/titletext' % myid), ('create', 'WindowsLook/Editbox', 'factory%d/title' % myid), ('create', 'WindowsLook/StaticText', 'factory%d/positionxtext' % myid), ('create', 'WindowsLook/Editbox', 'factory%d/positionx' % myid), ('create', 'WindowsLook/StaticText', 'factory%d/positionytext' % myid), ('create', 'WindowsLook/Editbox', 'factory%d/positiony' % myid), ('create', 'WindowsLook/StaticText', 'factory%d/positionztext' % myid), ('create', 'WindowsLook/Editbox', 'factory%d/positionz' % myid), ('create', 'WindowsLook/Button', 'factory%d/selectButton%d' % (myid, selid)), ('create', 'WindowsLook/Button', 'factory%d/acceptButton' % myid), ('create', 'WindowsLook/Button', 'factory%d/cancelButton' % myid)]) class MockPool(object): """ A mock version of a pool """ def __init__(self): pass class MockDirectoryService(object): """ A fake directory service object """ def __init__(self): self.pools = {1:MockPool()} def getDirectories(self): """ return the pools """ return self.pools class TestViewDirectories(TestCase): """ Tests for the ViewDirectories page. """ def test_getItems(self): """ Call getItems and make sure it returns the pool """ vdir = ViewDirectories(MockDirectoryService()) self.assertEqual(vdir.getItems(0, 100), vdir.target.pools.values())