fix overwriting of saved state.
[redakcja.git] / lib / vstorage / tests.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 #
4 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
5 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
6 #
7
8 import os
9 import tempfile
10 from nose.tools import *
11 from nose.core import runmodule
12
13 import vstorage
14
15 def clear_directory(top):
16     for root, dirs, files in os.walk(top, topdown=False):
17         for name in files:
18             os.remove(os.path.join(root, name))
19         for name in dirs:
20             os.rmdir(os.path.join(root, name))
21     try:
22         os.removedirs(top)
23     except OSError:
24         pass
25
26
27 class TestVersionedStorage(object):
28     def setUp(self):
29         self.repo_path = tempfile.mkdtemp()
30         self.repo = vstorage.VersionedStorage(self.repo_path)
31
32     def tearDown(self):
33         clear_directory(self.repo_path)
34
35     def test_save_text(self):
36         text = u"test text"
37         title = u"test title"
38         author = u"test author"
39         comment = u"test comment"
40
41         self.repo.save_text(
42             title=title,
43             text=text,
44             author=author,
45             comment=comment,
46             parent=None,
47         )
48
49         saved_text, rev = self.repo.page_text(title)
50         assert_equal(saved_text, text)
51         assert_equal(rev, 0)
52
53     def test_save_text_noparent(self):
54         text = u"test text"
55         title = u"test title"
56         author = u"test author"
57         comment = u"test comment"
58
59         self.repo.save_text(title=title,
60                     text=text, author=author,
61                     comment=comment, parent=None)
62
63
64         saved_text, rev = self.repo.page_text(title)
65         assert_equal(saved_text, text)
66         assert_equal(rev, 0)
67
68     def test_save_merge_no_conflict(self):
69         text = u"test\ntext"
70         title = u"test title"
71         author = u"test author"
72         comment = u"test comment"
73         self.repo.save_text(title=title,
74                     text=text, author=author,
75                     comment=comment, parent=None)
76         self.repo.save_text(title=title,
77                     text=text, author=author,
78                     comment=comment, parent=None)
79
80         saved_text, rev = self.repo.page_text(title)
81         assert_equal(saved_text, text)
82         assert_equal(rev, 0)
83
84     def test_save_merge_line_conflict(self):
85         text = u"test\ntest\n"
86         text1 = u"test\ntext\n"
87         text2 = u"text\ntest\n"
88         title = u"test title"
89         author = u"test author"
90         comment = u"test comment"
91
92         self.repo.save_text(title=title,
93                     text=text, author=author,
94                     comment=comment, parent=None)
95
96         saved_text, rev = self.repo.page_text(title)
97         assert_equal(saved_text, text)
98         assert_equal(rev, 0)
99
100         self.repo.save_text(title=title,
101                     text=text1, author=author,
102                     comment=comment, parent=0)
103
104         saved_text, rev = self.repo.page_text(title)
105         assert_equal(saved_text, text1)
106         assert_equal(rev, 1)
107
108         self.repo.save_text(title=title,
109                     text=text2, author=author,
110                     comment=comment, parent=0)
111
112         saved_text, rev = self.repo.page_text(title)
113         # Other conflict markers placement can also be correct
114         assert_equal(saved_text, u'''\
115 text
116 test
117 <<<<<<< local
118 =======
119 text
120 >>>>>>> other
121 ''')
122
123     def test_delete(self):
124         text = u"text test"
125         title = u"test title"
126         author = u"test author"
127         comment = u"test comment"
128         self.repo.save_text(title=title,
129                     text=text, author=author,
130                     comment=comment, parent=None)
131
132         ok_(title in self.repo, "Document not in repository.")
133
134         self.repo.delete_page(title, author, comment)
135
136         ok_(title not in self.repo, "Document in repository after delete")
137
138     @raises(vstorage.DocumentNotFound)
139     def test_document_not_found(self):
140         self.repo.page_text(u'unknown entity')
141
142     def test_open_existing_repository(self):
143         self.repo.save_text(title=u'Python!', text=u'ham and spam')
144         current_repo_revision = self.repo.repo_revision()
145         same_repo = vstorage.VersionedStorage(self.repo_path)
146         assert_equal(same_repo.repo_revision(), current_repo_revision)
147
148     def test_history(self):
149         COMMITS = [
150             {"author": "bunny", "text":"1", "comment": "Oh yeah!"},
151             {"author": "frank", "text":"2", "comment": "Second is the best!"},
152             {"text":"3", "comment": "Third"},
153             {"author": "welma", "text":"4", "comment": "Fourth"},
154         ]
155
156         for commit in COMMITS:
157             self.repo.save_text(title=u"Sample", **commit)
158
159         for n, entry in enumerate(reversed(list(self.repo.page_history(u"Sample")))):
160             assert_equal(entry["version"], n)
161             assert_equal(entry["author"], COMMITS[n].get("author", "anonymous"))
162             assert_equal(entry["description"], COMMITS[n]["comment"])
163             assert_equal(entry["tag"], [])
164
165     def test_data_revert(self):
166         COMMITS = [
167             {u"title": u"one", "author": "bunny", "text":"1.1", "comment": "1"},
168             {u"title": u"one", "author": "frank", "text":"1.2", "comment": "2"},
169             {u"title": u"two", "author": "bunny", "text":"2.1", "comment": "3"},
170             {u"title": u"one", "author": "frank", "text":"1.3", "comment": "4"},
171         ]
172
173         for commit in COMMITS:
174             self.repo.save_text(**commit)
175
176         # now revert last change on one
177         self.repo.revert(u"one", 0)
178         assert_equal(self.repo.page_text(u"one"), (u"1.1", 3))
179         assert_equal(self.repo.page_text(u"two"), (u"2.1", 0))
180
181         self.repo.revert(u"one", 2)
182         assert_equal(self.repo.page_text(u"one"), (u"1.3", 4))
183
184 class TestVSTags(object):
185
186     TITLE_1 = "Sample"
187
188     COMMITS = [
189         {"author": "bunny", "text":"1", "comment": "Oh yeah!"},
190         {"author": "frank", "text":"2", "comment": "Second is the best!"},
191         {"text":"3", "comment": "Third"},
192         {"author": "welma", "text":"4", "comment": "Fourth"},
193     ]
194
195     def setUp(self):
196         self.repo_path = tempfile.mkdtemp()
197         self.repo = vstorage.VersionedStorage(self.repo_path)
198
199         # generate some history
200         for commit in self.COMMITS:
201             self.repo.save_text(title=u"Sample", **commit)
202
203         # verify
204         for n, entry in enumerate(reversed(list(self.repo.page_history(self.TITLE_1)))):
205             assert_equal(entry["tag"], [])
206
207     def tearDown(self):
208         clear_directory(self.repo_path)
209
210     def test_add_tag(self):
211         TAG_USER = "mike_the_tagger"
212         TAG_NAME = "production"
213         TAG_VERSION = 2
214
215         # Add tag
216         self.repo.add_page_tag(self.TITLE_1, TAG_VERSION, TAG_NAME, TAG_USER)
217
218         # check history again
219         history = list(self.repo.page_history(self.TITLE_1))
220         for entry in reversed(history):
221             if entry["version"] == TAG_VERSION:
222                 assert_equal(entry["tag"], [TAG_NAME])
223             else:
224                 assert_equal(entry["tag"], [])
225
226     def test_add_many_tags(self):
227         TAG_USER = "mike_the_tagger"
228         tags = [
229             (2, "production", "mike"),
230             (2, "finished", "jeremy"),
231             (0, "original", "jeremy"),
232         ]
233
234         for rev, name, user in tags:
235             self.repo.add_page_tag(self.TITLE_1, rev, name, user)
236
237         # check history again
238         history = list(self.repo.page_history(self.TITLE_1))
239         for entry in reversed(history):
240             expected = [tag[1] for tag in tags if tag[0] == entry["version"]]
241             assert_equal(set(entry["tag"]), set(expected))