source: josm/trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogTest.java@ 15010

Last change on this file since 15010 was 15010, checked in by Don-vip, 5 years ago

fix #17634 - Reject uploads that do not follow comment/source upload policy, using the following 4 new properties:

  • upload.comment.forbidden-terms
  • upload.comment.mandatory-terms
  • upload.source.forbidden-terms
  • upload.source.mandatory-terms
  • Property svn:eol-style set to native
File size: 11.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNull;
7import static org.junit.Assert.assertTrue;
8
9import java.awt.GraphicsEnvironment;
10import java.util.Arrays;
11import java.util.List;
12import java.util.Map;
13import java.util.concurrent.ConcurrentHashMap;
14import java.util.function.Supplier;
15
16import javax.swing.JButton;
17import javax.swing.JOptionPane;
18
19import org.junit.Rule;
20import org.junit.Test;
21import org.openstreetmap.josm.TestUtils;
22import org.openstreetmap.josm.gui.ExtendedDialog;
23import org.openstreetmap.josm.gui.io.UploadDialog.UploadAction;
24import org.openstreetmap.josm.io.UploadStrategySpecification;
25import org.openstreetmap.josm.spi.preferences.Config;
26import org.openstreetmap.josm.testutils.JOSMTestRules;
27import org.openstreetmap.josm.testutils.mockers.ExtendedDialogMocker;
28import org.openstreetmap.josm.testutils.mockers.WindowMocker;
29
30import com.google.common.collect.ImmutableMap;
31
32import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
33import mockit.Invocation;
34import mockit.Mock;
35
36/**
37 * Unit tests of {@link UploadDialog} class.
38 */
39public class UploadDialogTest {
40
41 /**
42 * Setup tests
43 */
44 @Rule
45 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
46 public JOSMTestRules test = new JOSMTestRules().preferences();
47
48 private static class MockUploadDialog extends JOptionPane implements IUploadDialog {
49 private final String source;
50 private final String comment;
51
52 public int handleMissingCommentCalls;
53 public int handleMissingSourceCalls;
54
55 MockUploadDialog(final String comment, final String source) {
56 this.source = source;
57 this.comment = comment;
58 }
59
60 @Override
61 public void rememberUserInput() {
62 // Do nothing
63 }
64
65 @Override
66 public boolean isCanceled() {
67 return false;
68 }
69
70 @Override
71 public void handleMissingSource() {
72 this.handleMissingSourceCalls += 1;
73 }
74
75 @Override
76 public void handleMissingComment() {
77 this.handleMissingCommentCalls += 1;
78 }
79
80 @Override
81 public void handleIllegalChunkSize() {
82 // Do nothing
83 }
84
85 @Override
86 public UploadStrategySpecification getUploadStrategySpecification() {
87 return new UploadStrategySpecification();
88 }
89
90 @Override
91 public String getUploadSource() {
92 return source;
93 }
94
95 @Override
96 public String getUploadComment() {
97 return comment;
98 }
99
100 @Override
101 public Map<String, String> getTags(boolean keepEmpty) {
102 return new ConcurrentHashMap<>();
103 }
104
105 @Override
106 public void forceUpdateActiveField() {
107 // Do nothing
108 }
109 }
110
111 /**
112 * Test of {@link UploadDialog.CancelAction} class.
113 */
114 @Test
115 public void testCancelAction() {
116 if (GraphicsEnvironment.isHeadless()) {
117 TestUtils.assumeWorkingJMockit();
118 new WindowMocker();
119 }
120 MockUploadDialog uploadDialog = new MockUploadDialog(null, null);
121 new UploadDialog.CancelAction(uploadDialog).actionPerformed(null);
122 }
123
124 /**
125 * Test of {@link UploadDialog.UploadAction} class.
126 */
127 @Test
128 public void testUploadAction() {
129 TestUtils.assumeWorkingJMockit();
130 ExtendedDialogMocker edMocker = new ExtendedDialogMocker(
131 ImmutableMap.<String, Object>of(
132 "<html>Your upload comment is <i>empty</i>, or <i>very short</i>.<br /><br />This is "
133 + "technically allowed, but please consider that many users who are<br />watching changes "
134 + "in their area depend on meaningful changeset comments<br />to understand what is going "
135 + "on!<br /><br />If you spend a minute now to explain your change, you will make life<br />"
136 + "easier for many other mappers.</html>", "Revise",
137 "<html>You did not specify a source for your changes.<br />It is technically allowed, "
138 + "but this information helps<br />other users to understand the origins of the data."
139 + "<br /><br />If you spend a minute now to explain your change, you will make life"
140 + "<br />easier for many other mappers.</html>", "Revise"
141 )
142 ) {
143 @Mock
144 void setupDialog(Invocation invocation) throws Exception {
145 if (GraphicsEnvironment.isHeadless()) {
146 final int nButtons = ((String[]) TestUtils.getPrivateField(
147 ExtendedDialog.class, invocation.getInvokedInstance(), "bTexts")).length;
148 @SuppressWarnings("unchecked")
149 final List<JButton> buttons = (List<JButton>) TestUtils.getPrivateField(
150 ExtendedDialog.class, invocation.getInvokedInstance(), "buttons");
151
152 for (int i = 0; i < nButtons; i++) {
153 buttons.add(new JButton());
154 }
155 } else {
156 invocation.proceed();
157 }
158 }
159 };
160
161 MockUploadDialog uploadDialog = new MockUploadDialog("comment", "source");
162 new UploadDialog.UploadAction(uploadDialog).actionPerformed(null);
163
164 assertEquals(1, uploadDialog.handleMissingCommentCalls);
165 assertEquals(0, uploadDialog.handleMissingSourceCalls);
166 assertEquals(1, edMocker.getInvocationLog().size());
167 Object[] invocationLogEntry = edMocker.getInvocationLog().get(0);
168 assertEquals(1, (int) invocationLogEntry[0]);
169 assertEquals("Please revise upload comment", invocationLogEntry[2]);
170 edMocker.resetInvocationLog();
171
172 uploadDialog = new MockUploadDialog("", "source");
173 new UploadDialog.UploadAction(uploadDialog).actionPerformed(null);
174
175 assertEquals(1, uploadDialog.handleMissingCommentCalls);
176 assertEquals(0, uploadDialog.handleMissingSourceCalls);
177 assertEquals(1, edMocker.getInvocationLog().size());
178 invocationLogEntry = edMocker.getInvocationLog().get(0);
179 assertEquals(1, (int) invocationLogEntry[0]);
180 assertEquals("Please revise upload comment", invocationLogEntry[2]);
181 edMocker.resetInvocationLog();
182
183 uploadDialog = new MockUploadDialog("comment", "");
184 new UploadDialog.UploadAction(uploadDialog).actionPerformed(null);
185
186 assertEquals(1, uploadDialog.handleMissingCommentCalls);
187 assertEquals(0, uploadDialog.handleMissingSourceCalls);
188 assertEquals(1, edMocker.getInvocationLog().size());
189 invocationLogEntry = edMocker.getInvocationLog().get(0);
190 assertEquals(1, (int) invocationLogEntry[0]);
191 assertEquals("Please revise upload comment", invocationLogEntry[2]);
192 edMocker.resetInvocationLog();
193
194 uploadDialog = new MockUploadDialog("a comment long enough", "");
195 new UploadDialog.UploadAction(uploadDialog).actionPerformed(null);
196
197 assertEquals(0, uploadDialog.handleMissingCommentCalls);
198 assertEquals(1, uploadDialog.handleMissingSourceCalls);
199 assertEquals(1, edMocker.getInvocationLog().size());
200 invocationLogEntry = edMocker.getInvocationLog().get(0);
201 assertEquals(1, (int) invocationLogEntry[0]);
202 assertEquals("Please specify a changeset source", invocationLogEntry[2]);
203 edMocker.resetInvocationLog();
204
205 uploadDialog = new MockUploadDialog("a comment long enough", "a source long enough");
206 new UploadDialog.UploadAction(uploadDialog).actionPerformed(null);
207
208 assertEquals(0, uploadDialog.handleMissingCommentCalls);
209 assertEquals(0, uploadDialog.handleMissingSourceCalls);
210 assertEquals(0, edMocker.getInvocationLog().size());
211 }
212
213 /**
214 * Test of {@link UploadDialog.UploadAction#isUploadCommentTooShort} method.
215 */
216 @Test
217 public void testIsUploadCommentTooShort() {
218 assertTrue(UploadDialog.UploadAction.isUploadCommentTooShort(""));
219 assertTrue(UploadDialog.UploadAction.isUploadCommentTooShort("test"));
220 assertTrue(UploadDialog.UploadAction.isUploadCommentTooShort("测试"));
221 assertFalse(UploadDialog.UploadAction.isUploadCommentTooShort("geometric corrections"));
222 assertFalse(UploadDialog.UploadAction.isUploadCommentTooShort("几何校正"));
223 // test with unassigned unicode characters ==> no unicode block
224 assertTrue(UploadDialog.UploadAction.isUploadCommentTooShort("\u0860"));
225 }
226
227 private static void doTestGetLastChangesetTagFromHistory(String historyKey, Supplier<String> methodToTest, String def) {
228 Config.getPref().putList(historyKey, null);
229 Config.getPref().putInt(BasicUploadSettingsPanel.HISTORY_LAST_USED_KEY, 0);
230 Config.getPref().putInt(BasicUploadSettingsPanel.HISTORY_MAX_AGE_KEY, 30);
231 assertNull(methodToTest.get()); // age NOK (history empty)
232 Config.getPref().putList(historyKey, Arrays.asList("foo"));
233 assertNull(methodToTest.get()); // age NOK (history not empty)
234 Config.getPref().putLong(BasicUploadSettingsPanel.HISTORY_LAST_USED_KEY, System.currentTimeMillis() / 1000);
235 assertEquals("foo", methodToTest.get()); // age OK, history not empty
236 Config.getPref().putList(historyKey, null);
237 assertEquals(def, methodToTest.get()); // age OK, history empty
238 }
239
240 /**
241 * Test of {@link UploadDialog#getLastChangesetCommentFromHistory} method.
242 */
243 @Test
244 public void testGetLastChangesetCommentFromHistory() {
245 doTestGetLastChangesetTagFromHistory(
246 BasicUploadSettingsPanel.HISTORY_KEY,
247 UploadDialog::getLastChangesetCommentFromHistory,
248 null);
249 }
250
251 /**
252 * Test of {@link UploadDialog#getLastChangesetSourceFromHistory} method.
253 */
254 @Test
255 public void testGetLastChangesetSourceFromHistory() {
256 doTestGetLastChangesetTagFromHistory(
257 BasicUploadSettingsPanel.SOURCE_HISTORY_KEY,
258 UploadDialog::getLastChangesetSourceFromHistory,
259 BasicUploadSettingsPanel.getDefaultSources().get(0));
260 }
261
262 private static void doTestValidateUploadTag(String prefix) {
263 Config.getPref().putList(prefix + ".mandatory-terms", null);
264 Config.getPref().putList(prefix + ".forbidden-terms", null);
265 assertNull(UploadAction.validateUploadTag("foo", prefix));
266
267 Config.getPref().putList(prefix + ".mandatory-terms", Arrays.asList("foo"));
268 assertNull(UploadAction.validateUploadTag("foo", prefix));
269 assertEquals("The following required terms are missing: [foo]",
270 UploadAction.validateUploadTag("bar", prefix));
271
272 Config.getPref().putList(prefix + ".forbidden-terms", Arrays.asList("bar"));
273 assertNull(UploadAction.validateUploadTag("foo", prefix));
274 assertEquals("The following forbidden terms have been found: [bar]",
275 UploadAction.validateUploadTag("foobar", prefix));
276 }
277
278 /**
279 * Test of {@link UploadDialog.UploadAction#validateUploadTag} method.
280 */
281 @Test
282 public void testvalidateUploadTag() {
283 doTestValidateUploadTag("upload.comment");
284 doTestValidateUploadTag("upload.source");
285 }
286}
Note: See TracBrowser for help on using the repository browser.