Repository navigation
Expand file tree
/
Copy pathmark_nooverwrite_test.go
More file actions
188 lines (151 loc) · 6.67 KB
/
Copy pathmark_nooverwrite_test.go
File metadata and controls
188 lines (151 loc) · 6.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package mark
import (
"io"
"net/http"
"path/filepath"
"strings"
"testing"
"github.com/kovetskiy/mark/v16/confluence"
"github.com/kovetskiy/mark/v16/confluence/confluencetest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// noOverwriteFixture publishes one page and returns the server, its id and the
// config that produced it.
func noOverwriteFixture(t *testing.T) (*confluencetest.Server, string, Config) {
t.Helper()
server := confluencetest.New(t)
home := server.AddPage("DOCS", "Home", "page", "")
server.SetHomepage("DOCS", home.ID)
server.AddPage("DOCS", "Parent", "page", home.ID)
dir := t.TempDir()
writeFile(t, dir, "doc.md",
"<!-- Space: DOCS -->\n<!-- Parent: Parent -->\n<!-- Title: Doc -->\n\nFrom mark.\n")
config := Config{
BaseURL: server.URL, Username: "user", Password: "token",
Files: filepath.Join(dir, "*.md"),
Features: []string{"mention"},
TrackPages: true,
NoOverwrite: true,
Output: io.Discard,
}
require.NoError(t, Run(config))
api := confluence.NewAPI(server.URL, "user", "token", false)
doc, err := api.FindPage("DOCS", "Doc", "page")
require.NoError(t, err)
require.NotNil(t, doc)
return server, doc.ID, config
}
// TestNoOverwriteSkipsAPageEditedInConfluence is the point of the flag: an edit
// made in the web UI is not silently replaced on the next publish.
func TestNoOverwriteSkipsAPageEditedInConfluence(t *testing.T) {
server, id, config := noOverwriteFixture(t)
server.EditPage(id, "<p>Written by a person.</p>")
edited := server.Page(id)
require.NoError(t, Run(config))
after := server.Page(id)
assert.Equal(t, "<p>Written by a person.</p>", after.Body,
"the hand-written body must survive the run")
assert.Equal(t, edited.Version, after.Version,
"a skipped page must not gain a version")
}
// TestNoOverwriteKeepsReportingUntilResolved checks that the warning is not a
// one-off. The recorded version is deliberately left alone while a page is
// skipped, so every later run says so again.
func TestNoOverwriteKeepsReportingUntilResolved(t *testing.T) {
server, id, config := noOverwriteFixture(t)
server.EditPage(id, "<p>Written by a person.</p>")
require.NoError(t, Run(config))
require.NoError(t, Run(config))
assert.Equal(t, "<p>Written by a person.</p>", server.Page(id).Body,
"the second run must skip the page as well")
}
// TestNoOverwritePublishesAnUntouchedPage is the control. Without it the fix
// could be "stop publishing".
func TestNoOverwritePublishesAnUntouchedPage(t *testing.T) {
server, id, config := noOverwriteFixture(t)
before := server.Page(id)
require.NoError(t, Run(config))
after := server.Page(id)
assert.Contains(t, after.Body, "From mark",
"a page nobody touched must still be published")
assert.Greater(t, after.Version, before.Version,
"an untouched page is updated as usual")
}
// TestNoOverwriteDoesNotOrphanASkippedPage pins that a skipped page still
// counts as published. It is still on disk, and deleting it because a run
// declined to write to it would be the worst possible reading of the flag.
func TestNoOverwriteDoesNotOrphanASkippedPage(t *testing.T) {
server, id, config := noOverwriteFixture(t)
server.EditPage(id, "<p>Written by a person.</p>")
require.NoError(t, Run(config))
page := server.Page(id)
require.NotNil(t, page, "the page must not be deleted")
assert.Equal(t, "<p>Written by a person.</p>", page.Body,
"the page must have been skipped, which is the case being pinned")
}
// TestNoOverwriteRequiresTrackPages: without the manifest there is nowhere to
// have remembered a version, so the flag could only appear to work.
func TestNoOverwriteRequiresTrackPages(t *testing.T) {
server := confluencetest.New(t)
home := server.AddPage("DOCS", "Home", "page", "")
server.SetHomepage("DOCS", home.ID)
dir := t.TempDir()
writeFile(t, dir, "doc.md", "<!-- Space: DOCS -->\n<!-- Title: Doc -->\n\nBody.\n")
err := Run(Config{
BaseURL: server.URL, Username: "user", Password: "token",
Files: filepath.Join(dir, "*.md"), NoOverwrite: true, Output: io.Discard,
})
require.Error(t, err)
assert.Contains(t, err.Error(), "--track-pages")
}
// TestNoOverwriteSurvivesTheRunThatReportsIt covers the run after the warning,
// which is where the protection used to end.
//
// Reporting drift records the document as seen, so it is not mistaken for an
// orphan and deleted -- and recording it rebuilt the entry without the version,
// erasing the very baseline just reported against. The next run read a zero,
// concluded nothing had drifted, and overwrote the edit it had refused to touch
// the run before.
//
// The file has to change between the runs: an unchanged one takes an early
// return that never records, which is why the existing tests never saw this.
func TestNoOverwriteSurvivesTheRunThatReportsIt(t *testing.T) {
server, id, config := noOverwriteFixture(t)
server.EditPage(id, "<p>Written by a person.</p>")
// The run that reports the drift, with the document edited too.
writeFile(t, filepath.Dir(config.Files), "doc.md",
"<!-- Space: DOCS -->\n<!-- Parent: Parent -->\n<!-- Title: Doc -->\n\nSecond version.\n")
require.NoError(t, Run(config))
assert.Equal(t, "<p>Written by a person.</p>", server.Page(id).Body,
"the page must be left alone on the run that reports it")
// And the run after that, which had the baseline it needed taken away.
writeFile(t, filepath.Dir(config.Files), "doc.md",
"<!-- Space: DOCS -->\n<!-- Parent: Parent -->\n<!-- Title: Doc -->\n\nThird version.\n")
require.NoError(t, Run(config))
assert.Equal(t, "<p>Written by a person.</p>", server.Page(id).Body,
"the hand-written page must still be there")
}
// TestNoOverwriteDoesNotRetryOverAnEditMadeMidRun: an update refused as a
// conflict is retried against the page's current version, which overwrites
// whatever caused the conflict. An edit that lands after the drift check and
// before the update is the one --no-overwrite is there for, so the retry must
// not go over it.
func TestNoOverwriteDoesNotRetryOverAnEditMadeMidRun(t *testing.T) {
server, id, config := noOverwriteFixture(t)
writeFile(t, filepath.Dir(config.Files), "doc.md",
"<!-- Space: DOCS -->\n<!-- Parent: Parent -->\n<!-- Title: Doc -->\n\nSecond version.\n")
edited := false
server.SetFail(func(r *http.Request) (int, string, bool) {
if r.Method == http.MethodPut && strings.HasSuffix(r.URL.Path, "/content/"+id) && !edited {
edited = true
server.EditPage(id, "<p>Written by a person.</p>")
}
return 0, "", false
})
err := Run(config)
require.Error(t, err)
assert.Contains(t, err.Error(), "edited in Confluence while mark was publishing it")
assert.Equal(t, "<p>Written by a person.</p>", server.Page(id).Body,
"the edit made during the run must survive it")
}