Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 1a8621c

Browse files
authored
Merge branch 'master' into bump-up-version-juha
2 parents c96c686 + d239f28 commit 1a8621c

File tree

5 files changed

+125
-32
lines changed

5 files changed

+125
-32
lines changed

src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020

2121
import java.nio.file.Path;
2222
import java.util.ArrayList;
23+
import java.util.LinkedHashMap;
2324
import java.util.List;
25+
import java.util.Map;
26+
import java.util.Map.Entry;
2427

2528
@Command(name = "download", desc = "Download exercises for a specific course")
2629
public class DownloadExercisesCommand extends AbstractCommand {
@@ -85,34 +88,44 @@ public void run(CommandLine args, Io io) {
8588
// TODO This method could be moved somewhere else.
8689
private Course findCourse(String courseName) {
8790
Io io = ctx.getIo();
88-
Course found = null;
89-
boolean hasDuplicateNames = false;
9091

9192
List<Settings> accountsList = SettingsIo.getSettingsList();
93+
// LinkedHashMap is used here to preserve ordering.
94+
Map<Settings, Course> matches = new LinkedHashMap<>();
9295

9396
for (Settings settings : accountsList) {
9497
ctx.useSettings(settings);
9598
Course course = TmcUtil.findCourse(ctx, courseName);
96-
if (course == null) {
97-
continue;
99+
if (course != null) {
100+
matches.put(settings, course);
98101
}
99-
if (found != null) {
100-
if (!hasDuplicateNames) {
101-
io.println("There is multiple courses with same name at different servers.");
102-
}
103-
if (io.readConfirmation("Download course from "
104-
+ settings.getServerAddress(), false)) {
105-
return course;
106-
}
107-
hasDuplicateNames = true;
108-
}
109-
found = course;
110102
}
111-
if (found == null) {
103+
104+
if (matches.size() == 1) {
105+
Entry<Settings, Course> firstEntry = matches.entrySet().iterator().next();
106+
ctx.useSettings(firstEntry.getKey());
107+
return firstEntry.getValue();
108+
} else if (matches.isEmpty()) {
112109
io.println("Course doesn't exist.");
113110
return null;
114111
}
115-
return found;
112+
113+
io.println("There is " + matches.size()
114+
+ " courses with same name at different servers.");
115+
116+
for (Entry<Settings, Course> entrySet : matches.entrySet()) {
117+
Settings settings = entrySet.getKey();
118+
Course course = entrySet.getValue();
119+
120+
if (io.readConfirmation("Download course from "
121+
+ settings.getServerAddress() + " with '"
122+
+ settings.getUsername() + "' account", false)) {
123+
ctx.useSettings(settings);
124+
return course;
125+
}
126+
}
127+
io.println("The previous course was last that matched.");
128+
return null;
116129
}
117130

118131
private List<Exercise> getFilteredExercises(Course course) {
@@ -134,6 +147,7 @@ private List<Exercise> getFilteredExercises(Course course) {
134147
private void printStatistics(Course course, int requestCount, int downloadCount) {
135148
Io io = ctx.getIo();
136149
String courseName = course.getName();
150+
137151
if (course.getExercises().isEmpty()) {
138152
io.println("The '" + courseName + "' course doesn't have any exercises.");
139153
} else {

src/main/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdater.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ public boolean run() {
7878
File destination = new File(currentBinLocation + binName);
7979

8080
io.println("Downloading...");
81-
fetchTmcCliBinary(dlUrl, destination);
81+
if (!fetchTmcCliBinary(dlUrl, destination)) {
82+
return false;
83+
}
8284

8385
io.println("Running " + destination.getAbsolutePath());
8486
return runNewTmcCliBinary(destination.getAbsolutePath());
@@ -136,16 +138,18 @@ protected String fetchLatestReleaseJson() {
136138
* Downloads a binary file from downloadUrl and saves it to destination
137139
* file.
138140
*/
139-
protected void fetchTmcCliBinary(String downloadUrl, File destination) {
141+
protected boolean fetchTmcCliBinary(String downloadUrl, File destination) {
140142
byte[] content = fetchHttpEntity(downloadUrl);
141143
if (content == null) {
142144
io.println("Failed to download tmc-cli.");
143-
return;
145+
return false;
144146
}
145147
try {
146148
FileUtils.writeByteArrayToFile(destination, content);
149+
return true;
147150
} catch (IOException ex) {
148151
io.println("Failed to write the new version into \'" + destination + "\'.");
152+
return false;
149153
}
150154
}
151155

src/test/java/fi/helsinki/cs/tmc/cli/command/DocumentCommandTest.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package fi.helsinki.cs.tmc.cli.command;
22

3+
import static org.mockito.Mockito.when;
4+
import static org.powermock.api.mockito.PowerMockito.mockStatic;
5+
36
import fi.helsinki.cs.tmc.cli.Application;
47
import fi.helsinki.cs.tmc.cli.CliContext;
8+
import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil;
59
import fi.helsinki.cs.tmc.cli.io.TestIo;
610

711
import org.junit.Before;
812
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
import org.powermock.core.classloader.annotations.PrepareForTest;
15+
import org.powermock.modules.junit4.PowerMockRunner;
916

17+
@RunWith(PowerMockRunner.class)
18+
@PrepareForTest(EnvironmentUtil.class)
1019
public class DocumentCommandTest {
1120

1221
private Application app;
@@ -18,14 +27,28 @@ public void setUp() {
1827
io = new TestIo();
1928
ctx = new CliContext(io);
2029
app = new Application(ctx);
30+
31+
mockStatic(EnvironmentUtil.class);
32+
when(EnvironmentUtil.getTerminalWidth()).thenReturn(100);
2133
}
2234

2335
@Test
2436
public void run() throws InterruptedException {
37+
when(EnvironmentUtil.isWindows()).thenReturn(false);
38+
app = new Application(ctx);
39+
40+
String[] args = {"document", "-s", "0"};
41+
app.run(args);
42+
io.assertContains("Original dev team");
43+
}
44+
45+
@Test
46+
public void failOnWindows() throws InterruptedException {
47+
when(EnvironmentUtil.isWindows()).thenReturn(true);
2548
app = new Application(ctx);
2649

2750
String[] args = {"document", "-s", "0"};
2851
app.run(args);
29-
io.assertContains("dev team");
52+
io.assertContains("Command document doesn't exist");
3053
}
3154
}

src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package fi.helsinki.cs.tmc.cli.command;
22

3+
import static org.junit.Assert.assertEquals;
34
import static org.junit.Assert.assertTrue;
45
import static org.mockito.Matchers.any;
56
import static org.mockito.Matchers.anyListOf;
@@ -9,6 +10,7 @@
910
import static org.mockito.Mockito.spy;
1011
import static org.mockito.Mockito.when;
1112
import static org.powermock.api.mockito.PowerMockito.mockStatic;
13+
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
1214

1315
import fi.helsinki.cs.tmc.cli.Application;
1416
import fi.helsinki.cs.tmc.cli.CliContext;
@@ -27,11 +29,12 @@
2729

2830
import org.junit.After;
2931
import org.junit.Before;
30-
import org.junit.Ignore;
3132
import org.junit.Test;
3233
import org.junit.runner.RunWith;
34+
import org.mockito.ArgumentCaptor;
3335
import org.powermock.core.classloader.annotations.PrepareForTest;
3436
import org.powermock.modules.junit4.PowerMockRunner;
37+
import org.powermock.reflect.Whitebox;
3538

3639
import java.io.File;
3740
import java.io.IOException;
@@ -205,19 +208,68 @@ public void failsToLoadExercises() throws ParseException {
205208
io.assertContains("and of which 1 failed.");
206209
}
207210

208-
@Ignore
209211
@Test
210212
public void findFromMultipleServer() {
211-
List<Course> list1 = Arrays.asList(new Course("course1"));
212-
List<Course> list2 = Arrays.asList(new Course("course2"));
213-
when(TmcUtil.listCourses(eq(ctx))).thenReturn(list1).thenReturn(list2);
213+
Settings settings1 = new Settings("http://test.test", "", "");
214+
Settings settings2 = new Settings("http://hello.test", "", "");
215+
216+
when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1"))
217+
.thenReturn(new Course("course2"));
218+
when(SettingsIo.getSettingsList()).thenReturn(
219+
Arrays.asList(settings1, settings2));
220+
221+
String[] args = {"download", "course2"};
222+
app.run(args);
214223
}
215224

216-
@Ignore
217225
@Test
218-
public void findFromMultipleServerWithSameName() {
219-
List<Course> list1 = Arrays.asList(new Course("course1"));
220-
List<Course> list2 = Arrays.asList(new Course("course1"));
221-
when(TmcUtil.listCourses(eq(ctx))).thenReturn(list1).thenReturn(list2);
226+
public void findFromMultipleServerWithSameNameWithoutTakingAny() {
227+
Settings settings1 = new Settings("http://test.test", "abc", "");
228+
Settings settings2 = new Settings("http://hello.test", "def", "");
229+
230+
when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1"))
231+
.thenReturn(new Course("course1"));
232+
when(SettingsIo.getSettingsList()).thenReturn(
233+
Arrays.asList(settings1, settings2));
234+
235+
List<Exercise> exercises = Arrays.asList();
236+
when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class),
237+
any(ProgressObserver.class))).thenReturn(exercises);
238+
239+
String[] args = {"download", "course1"};
240+
io.addConfirmationPrompt(false);
241+
io.addConfirmationPrompt(false);
242+
app.run(args);
243+
io.assertContains("There is 2 courses with same name at different servers");
244+
io.assertContains("Download course from http://test.test with 'abc' account");
245+
io.assertContains("Download course from http://hello.test with 'def' account");
246+
io.assertContains("The previous course was last that matched");
247+
io.assertAllPromptsUsed();
248+
}
249+
250+
@Test
251+
public void findFromMultipleServerWithSameNameWithTakingFirst() {
252+
Settings settings1 = new Settings("http://test.test", "abc", "");
253+
Settings settings2 = new Settings("http://hello.test", "def", "");
254+
255+
when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1"))
256+
.thenReturn(new Course("course1"));
257+
when(SettingsIo.getSettingsList()).thenReturn(
258+
Arrays.asList(settings1, settings2));
259+
260+
String[] args = {"download", "course1"};
261+
io.addConfirmationPrompt(true);
262+
app.run(args);
263+
io.assertContains("There is 2 courses with same name at different servers");
264+
io.assertContains("Download course from http://test.test with 'abc' account");
265+
io.assertAllPromptsUsed();
266+
267+
ArgumentCaptor<CliContext> ctxCaptor = ArgumentCaptor.forClass(CliContext.class);
268+
verifyStatic();
269+
TmcUtil.downloadExercises(ctxCaptor.capture(), anyListOf(Exercise.class),
270+
any(ProgressObserver.class));
271+
272+
Settings usedSettings = Whitebox.getInternalState(ctx, "settings");
273+
assertEquals(usedSettings, settings1);
222274
}
223275
}

src/test/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdaterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void downloadsAndRunsNewBinaryIfOk() {
107107
TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false));
108108
doReturn(latestJson).when(updater).fetchLatestReleaseJson();
109109
//when(updater.fetchLatestReleaseJson()).thenReturn(latestJson);
110-
doNothing().when(updater).fetchTmcCliBinary(any(String.class), any(File.class));
110+
doReturn(true).when(updater).fetchTmcCliBinary(any(String.class), any(File.class));
111111
when(updater.runNewTmcCliBinary(any(String.class))).thenReturn(true);
112112
updater.run();
113113
assertThat(io.out(), containsString("A new version of tmc-cli is available!"));

0 commit comments

Comments
 (0)