| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2012,2013 Steffen Hoffmann <hoff.st@web.de> |
|---|
| 4 | # |
|---|
| 5 | # This software is licensed as described in the file COPYING, which |
|---|
| 6 | # you should have received as part of this distribution. |
|---|
| 7 | # |
|---|
| 8 | |
|---|
| 9 | import shutil |
|---|
| 10 | import tempfile |
|---|
| 11 | import unittest |
|---|
| 12 | |
|---|
| 13 | from trac.perm import PermissionCache, PermissionSystem |
|---|
| 14 | from trac.resource import Resource |
|---|
| 15 | from trac.test import EnvironmentStub, MockRequest |
|---|
| 16 | |
|---|
| 17 | from tractags.db import TagSetup |
|---|
| 18 | from tractags.model import resource_tags, tag_resource, tagged_resources |
|---|
| 19 | from tractags.wiki import WikiTagProvider |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | class TagModelTestCase(unittest.TestCase): |
|---|
| 23 | |
|---|
| 24 | def setUp(self): |
|---|
| 25 | self.env = EnvironmentStub(default_data=True, |
|---|
| 26 | enable=['trac.*', 'tractags.*']) |
|---|
| 27 | self.env.path = tempfile.mkdtemp() |
|---|
| 28 | self.perms = PermissionSystem(self.env) |
|---|
| 29 | self.req = MockRequest(self.env, authname='editor') |
|---|
| 30 | |
|---|
| 31 | self.check_perm = WikiTagProvider(self.env).check_permission |
|---|
| 32 | setup = TagSetup(self.env) |
|---|
| 33 | # Current tractags schema is setup with enabled component anyway. |
|---|
| 34 | # Revert these changes for getting default permissions inserted. |
|---|
| 35 | self._revert_tractags_schema_init() |
|---|
| 36 | setup.upgrade_environment() |
|---|
| 37 | |
|---|
| 38 | # Populate table with initial test data. |
|---|
| 39 | self.env.db_transaction(""" |
|---|
| 40 | INSERT INTO tags (tagspace, name, tag) |
|---|
| 41 | VALUES ('wiki', 'WikiStart', 'tag1') |
|---|
| 42 | """) |
|---|
| 43 | self.realm = 'wiki' |
|---|
| 44 | |
|---|
| 45 | def tearDown(self): |
|---|
| 46 | self.env.shutdown() |
|---|
| 47 | shutil.rmtree(self.env.path) |
|---|
| 48 | |
|---|
| 49 | # Helpers |
|---|
| 50 | |
|---|
| 51 | def _revert_tractags_schema_init(self): |
|---|
| 52 | with self.env.db_transaction as db: |
|---|
| 53 | db("DROP TABLE IF EXISTS tags") |
|---|
| 54 | db("DROP TABLE IF EXISTS tags_change") |
|---|
| 55 | db("DELETE FROM system WHERE name='tags_version'") |
|---|
| 56 | db("DELETE FROM permission WHERE action %s" % db.like(), |
|---|
| 57 | ('TAGS_%',)) |
|---|
| 58 | |
|---|
| 59 | def _tags(self): |
|---|
| 60 | tags = {} |
|---|
| 61 | for name, tag in self.env.db_query(""" |
|---|
| 62 | SELECT name,tag FROM tags |
|---|
| 63 | """): |
|---|
| 64 | if name in tags: |
|---|
| 65 | tags[name].add(tag) |
|---|
| 66 | else: |
|---|
| 67 | tags[name] = set([tag]) |
|---|
| 68 | return tags |
|---|
| 69 | |
|---|
| 70 | # Tests |
|---|
| 71 | |
|---|
| 72 | def test_get_tags(self): |
|---|
| 73 | resource = Resource(self.realm, 'WikiStart') |
|---|
| 74 | self.assertEquals([tag for tag in resource_tags(self.env, resource)], |
|---|
| 75 | ['tag1']) |
|---|
| 76 | |
|---|
| 77 | def test_get_tagged_resource_no_perm(self): |
|---|
| 78 | self.perms.revoke_permission('anonymous', 'WIKI_VIEW') |
|---|
| 79 | perm = PermissionCache(self.env) |
|---|
| 80 | tags = set(['tag1']) |
|---|
| 81 | # Don't yield resource without permission - 'WIKI_VIEW' here. |
|---|
| 82 | self.assertEqual([(res, tags) for res, tags |
|---|
| 83 | in tagged_resources(self.env, self.check_perm, perm, |
|---|
| 84 | self.realm, tags)], []) |
|---|
| 85 | |
|---|
| 86 | def test_get_tagged_resource(self): |
|---|
| 87 | perm = PermissionCache(self.env) |
|---|
| 88 | resource = Resource(self.realm, 'WikiStart') |
|---|
| 89 | tags = set(['tag1']) |
|---|
| 90 | self.assertEqual([(res, tags) for res, tags |
|---|
| 91 | in tagged_resources(self.env, self.check_perm, perm, |
|---|
| 92 | self.realm, tags)], |
|---|
| 93 | [(resource, tags)]) |
|---|
| 94 | |
|---|
| 95 | def test_reparent(self): |
|---|
| 96 | resource = Resource(self.realm, 'TaggedPage') |
|---|
| 97 | old_name = 'WikiStart' |
|---|
| 98 | tag_resource(self.env, resource, 'WikiStart', self.req.authname) |
|---|
| 99 | self.assertEquals(dict(TaggedPage=set(['tag1'])), self._tags()) |
|---|
| 100 | |
|---|
| 101 | def test_tag_changes(self): |
|---|
| 102 | # Add previously untagged resource. |
|---|
| 103 | resource = Resource(self.realm, 'TaggedPage') |
|---|
| 104 | tags = set(['tag1']) |
|---|
| 105 | tag_resource(self.env, resource, author=self.req.authname, tags=tags) |
|---|
| 106 | self.assertEquals(dict(TaggedPage=tags, WikiStart=tags), self._tags()) |
|---|
| 107 | # Add new tag to already tagged resource. |
|---|
| 108 | resource = Resource(self.realm, 'WikiStart') |
|---|
| 109 | tags = set(['tag1', 'tag2']) |
|---|
| 110 | tag_resource(self.env, resource, author=self.req.authname, tags=tags) |
|---|
| 111 | self.assertEquals(dict(TaggedPage=set(['tag1']), WikiStart=tags), |
|---|
| 112 | self._tags()) |
|---|
| 113 | # Exchange tags for already tagged resource. |
|---|
| 114 | tags = set(['tag1', 'tag3']) |
|---|
| 115 | tag_resource(self.env, resource, author=self.req.authname, tags=tags) |
|---|
| 116 | self.assertEquals(dict(TaggedPage=set(['tag1']), WikiStart=tags), |
|---|
| 117 | self._tags()) |
|---|
| 118 | # Delete a subset of tags for already tagged resource. |
|---|
| 119 | tags = set(['tag3']) |
|---|
| 120 | tag_resource(self.env, resource, author=self.req.authname, tags=tags) |
|---|
| 121 | self.assertEquals(dict(TaggedPage=set(['tag1']), WikiStart=tags), |
|---|
| 122 | self._tags()) |
|---|
| 123 | # Empty tag iterable deletes all resource tag references. |
|---|
| 124 | tags = tuple() |
|---|
| 125 | tag_resource(self.env, resource, author=self.req.authname, tags=tags) |
|---|
| 126 | self.assertEquals(dict(TaggedPage=set(['tag1'])), self._tags()) |
|---|
| 127 | |
|---|
| 128 | |
|---|
| 129 | def test_suite(): |
|---|
| 130 | suite = unittest.TestSuite() |
|---|
| 131 | suite.addTest(unittest.makeSuite(TagModelTestCase)) |
|---|
| 132 | return suite |
|---|
| 133 | |
|---|
| 134 | if __name__ == '__main__': |
|---|
| 135 | unittest.main(defaultTest='test_suite') |
|---|