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

Commit 2889b8a

Browse files
author
Irene
committed
Add tests, fix one liner command when slug invalid
1 parent 9411563 commit 2889b8a

17 files changed

Lines changed: 441 additions & 71 deletions

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@
116116
<artifactId>maven-compiler-plugin</artifactId>
117117
<version>3.5.1</version>
118118
<configuration>
119-
<source>1.7</source>
120-
<target>1.7</target>
119+
<source>${maven.compiler.source}</source>
120+
<target>${maven.compiler.source}</target>
121121
<compilerArgument>-Xlint:unchecked</compilerArgument>
122122
</configuration>
123123
<executions>

src/main/java/fi/helsinki/cs/tmc/cli/Application.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public Application(CliContext context) {
7676

7777
private boolean runCommand(String name, String[] args) {
7878
String[] commandName = name.split(" ");
79-
AbstractCommand command = CommandFactory.createCommand(commandName[0]);
79+
AbstractCommand command = CommandFactory.createCommand(commandName[0].trim().toLowerCase());
8080
if (command == null) {
8181
io.errorln("Command " + name + " doesn't exist.");
8282
return false;

src/main/java/fi/helsinki/cs/tmc/cli/backend/Account.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
public class Account {
1313

14-
static Account NULL_ACCOUNT = new Account(null, null, null);
14+
static Account NULL_ACCOUNT = new Account(null, null, null, null);
1515

1616
private String serverAddress;
1717
private String username;
@@ -25,10 +25,17 @@ public class Account {
2525
public Account() {}
2626

2727
public Account(String serverAddress, String username, String password) {
28-
this.serverAddress = serverAddress;
29-
this.username = username;
30-
this.password = password;
31-
this.organization = new Organization("Default", "lolled", "default", "lolled", false);
28+
this.serverAddress = serverAddress == null ? null : serverAddress.trim();
29+
this.username = username == null ? null : username.trim();
30+
this.password = password == null ? null : password.trim();
31+
}
32+
33+
34+
public Account(String serverAddress, String username, String password, Organization organization) {
35+
this.serverAddress = serverAddress == null ? null : serverAddress.trim();
36+
this.username = username == null ? null : username.trim();
37+
this.password = password == null ? null : password.trim();
38+
this.organization = organization;
3239
}
3340

3441
public Optional<String> getServerAddress() {
@@ -61,7 +68,7 @@ public boolean equals(Object obj) {
6168
}
6269

6370
public void setServerAddress(String serverAddress) {
64-
this.serverAddress = serverAddress;
71+
this.serverAddress = serverAddress.trim();
6572
}
6673

6774
public Optional<OauthCredentials> getOauthCredentials() {
@@ -73,7 +80,10 @@ public void setOauthCredentials(Optional<OauthCredentials> oauthCredentials) {
7380
}
7481

7582
public void setPassword(Optional<String> password) {
76-
this.password = password.orNull();
83+
if (password.isPresent()) {
84+
this.password = password.get().trim();
85+
}
86+
this.password = null;
7787
}
7888

7989
public Optional<String> getoAuthToken() {
@@ -88,18 +98,6 @@ public Optional<Course> getCurrentCourse() {
8898
return Optional.fromNullable(currentCourse);
8999
}
90100

91-
@Override
92-
public String toString() {
93-
return "Account{" +
94-
"serverAddress='" + serverAddress + '\'' +
95-
", username='" + username + '\'' +
96-
", password='" + password + '\'' +
97-
", oauthCredentials='" + oauthCredentials + '\'' +
98-
", token='" + token + '\'' +
99-
", currentCourse='" + currentCourse + '\'' +
100-
'}';
101-
}
102-
103101
public void setCurrentCourse(Optional<Course> currentCourse) {
104102
this.currentCourse = currentCourse.orNull();
105103
}

src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public Settings() {
2323
this.account = Account.NULL_ACCOUNT;
2424
}
2525

26-
public Settings(String serverAddress, String username, String password) {
27-
this.account = new Account(serverAddress, username, password);
26+
public Settings(String serverAddress, String username, String password, Organization organization) {
27+
this.account = new Account(serverAddress, username, password, organization);
2828
}
2929

3030
/**

src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult;
88
import fi.helsinki.cs.tmc.core.domain.Course;
99
import fi.helsinki.cs.tmc.core.domain.Exercise;
10+
import fi.helsinki.cs.tmc.core.domain.Organization;
1011
import fi.helsinki.cs.tmc.core.domain.ProgressObserver;
1112
import fi.helsinki.cs.tmc.core.domain.submission.FeedbackAnswer;
1213
import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult;
@@ -15,6 +16,7 @@
1516
import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult;
1617
import fi.helsinki.cs.tmc.langs.domain.RunResult;
1718

19+
import org.apache.commons.compress.archivers.sevenz.CLI;
1820
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
1921
import org.slf4j.Logger;
2022
import org.slf4j.LoggerFactory;
@@ -84,6 +86,19 @@ public static List<Course> listCourses(CliContext ctx) {
8486
return new ArrayList<>();
8587
}
8688

89+
public static List<Organization> getOrganizationsFromServer(CliContext ctx) {
90+
Callable<List<Organization>> callable;
91+
callable = ctx.getTmcCore().getOrganizations(ProgressObserver.NULL_OBSERVER);
92+
93+
try {
94+
return callable.call();
95+
} catch (Exception e) {
96+
TmcUtil.handleTmcExceptions(ctx, e);
97+
TmcUtil.logger.error("Failed to get organizations from server", e);
98+
}
99+
return new ArrayList();
100+
}
101+
87102
private static Course getDetails(CliContext ctx, Course course) {
88103
try {
89104
TmcCore core = ctx.getTmcCore();
@@ -218,25 +233,40 @@ private static void handleTmcExceptions(CliContext ctx, Exception exception) {
218233
io.errorln("Your username or password is not valid anymore.");
219234
return;
220235
}
236+
237+
if (exception instanceof IllegalArgumentException) {
238+
logger.error("Invalid arguments", exception);
239+
io.errorln("Please give server, username and password in valid form.");
240+
return;
241+
}
242+
221243
if (cause instanceof FailedHttpResponseException) {
222244
logger.error("Unable to connect to server", exception);
223245
io.errorln("Unable to connect to server.");
224246
return;
225247
}
248+
249+
if (exception instanceof UnknownHostException) {
250+
logger.error("Unknown host", exception);
251+
io.errorln("Unknwon host, check the server address.");
252+
return;
253+
}
254+
226255
if (cause instanceof ObsoleteClientException) {
227256
logger.error("Outdated tmc client");
228257
io.errorln("Your tmc-cli is outdated. Please update it.");
229258
ctx.getApp().runAutoUpdate();
230259
return;
231260
}
261+
232262
if (cause != null && cause.getCause() instanceof UnknownHostException) {
233263
logger.error("No internet connection");
234264
io.errorln("You have no internet connection.");
235265
return;
236266
}
237267
logger.error("Command failed in tmc-core", exception);
238268
//TODO we seem to write twice error message; here and in the commands.
239-
io.errorln("Command failed in tmc-core, check tmc-cli.log file for more info");
269+
io.errorln("Command failed, check tmc-cli.log file for more info");
240270
}
241271

242272
private static boolean isAuthenticationError(Exception exception) {

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
import fi.helsinki.cs.tmc.cli.core.Command;
1111
import fi.helsinki.cs.tmc.cli.io.Io;
1212

13+
import fi.helsinki.cs.tmc.core.domain.Organization;
1314
import org.apache.commons.cli.CommandLine;
1415
import org.apache.commons.cli.Option;
1516
import org.apache.commons.cli.Options;
1617

1718
import com.google.common.base.Optional;
1819

20+
import java.util.concurrent.Callable;
21+
1922
@Command(name = "login", desc = "Login to TMC server")
2023
public class LoginCommand extends AbstractCommand {
2124

@@ -25,7 +28,6 @@ public class LoginCommand extends AbstractCommand {
2528
private String serverAddress;
2629
private String username;
2730
private String password;
28-
private String oAuthToken;
2931

3032
@Override
3133
public String[] getUsages() {
@@ -37,6 +39,7 @@ public void getOptions(Options options) {
3739
options.addOption("u", "user", true, "TMC username");
3840
options.addOption("p", "password", true, "Password for the user");
3941
options.addOption("s", "server", true, "Address for TMC server");
42+
options.addOption("o", "organization", true, "TMC organization");
4043
}
4144

4245
@Override
@@ -70,11 +73,20 @@ public void run(CliContext context, CommandLine args) {
7073
username = getLoginInfo(args, username, "u", "username: ");
7174
password = getLoginInfo(args, null, "p", "password: ");
7275

76+
OrganizationCommand organizationCommand = new OrganizationCommand();
7377
Account account = new Account(serverAddress, username, null);
7478
if (!TmcUtil.tryToLogin(ctx, account, password)) {
7579
return;
7680
}
7781

82+
Optional<Organization> organization = organizationCommand.chooseOrganization(ctx, args);
83+
if (!organization.isPresent()) {
84+
return;
85+
}
86+
Account currentAccount = this.ctx.getSettings().getAccount();
87+
currentAccount.setOrganization(organization);
88+
this.ctx.getSettings().setAccount(currentAccount);
89+
7890
AccountList list = SettingsIo.loadAccountList();
7991
list.addAccount(account);
8092
if (!SettingsIo.saveAccountList(list)) {
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package fi.helsinki.cs.tmc.cli.command;
2+
3+
import fi.helsinki.cs.tmc.cli.backend.Account;
4+
import fi.helsinki.cs.tmc.cli.backend.TmcUtil;
5+
import fi.helsinki.cs.tmc.cli.core.AbstractCommand;
6+
import fi.helsinki.cs.tmc.cli.core.CliContext;
7+
import fi.helsinki.cs.tmc.cli.core.Command;
8+
import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil;
9+
import fi.helsinki.cs.tmc.cli.io.Io;
10+
import fi.helsinki.cs.tmc.cli.utils.OptionalToGoptional;
11+
import fi.helsinki.cs.tmc.core.domain.Organization;
12+
import org.apache.commons.cli.CommandLine;
13+
import org.apache.commons.cli.Options;
14+
15+
import java.util.ArrayList;
16+
import java.util.Comparator;
17+
import java.util.List;
18+
import com.google.common.base.Optional;
19+
20+
@Command(name = "organization", desc = "Change organization")
21+
public class OrganizationCommand extends AbstractCommand {
22+
23+
private CliContext ctx;
24+
private Io io;
25+
26+
@Override
27+
public void getOptions(Options options) {
28+
options.addOption("o", "organization", true, "Slug of organization");
29+
}
30+
31+
@Override
32+
public void run(CliContext ctx, CommandLine args) {
33+
Optional<Organization> organization = chooseOrganization(ctx, args);
34+
Account currentAccount = this.ctx.getSettings().getAccount();
35+
currentAccount.setOrganization(organization);
36+
this.ctx.getSettings().setAccount(currentAccount);
37+
}
38+
39+
private List<Organization> listOrganizations() {
40+
if (!ctx.loadBackend()) {
41+
return null;
42+
}
43+
List<Organization> organizations = TmcUtil.getOrganizationsFromServer(ctx);
44+
return organizations;
45+
}
46+
47+
private void printOrganizations(List<Organization> organizations, boolean pager) {
48+
if (organizations.isEmpty()) {
49+
io.print("No organizations found.");
50+
return;
51+
}
52+
List<Organization> pinned = new ArrayList();
53+
List<Organization> others = new ArrayList();
54+
organizations.stream()
55+
.sorted(Comparator.comparing(Organization::getName))
56+
.forEach(o -> {
57+
if (o.isPinned()) {
58+
pinned.add(o);
59+
} else {
60+
others.add(o);
61+
}
62+
});
63+
System.out.println();
64+
pinned.stream().forEach(o -> printFormattedOrganization(o));
65+
System.out.println("----------");
66+
others.stream().forEach(o -> printFormattedOrganization(o));
67+
System.out.println();
68+
}
69+
70+
private void printFormattedOrganization(Organization o) {
71+
io.println(o.getName() + " (slug: " + o.getSlug() + ")");
72+
}
73+
74+
75+
private String getOrganizationFromUser(List<Organization> organizations, CommandLine line, boolean printOptions, boolean oneLine) {
76+
if (oneLine && line.hasOption("o")) {
77+
return line.getOptionValue("o");
78+
}
79+
if (printOptions) {
80+
printOrganizations(organizations, !line.hasOption("n") && !EnvironmentUtil.isWindows());
81+
}
82+
return io.readLine("Choose organization by writing its slug: ");
83+
}
84+
85+
86+
public Optional<Organization> chooseOrganization(CliContext ctx, CommandLine args) {
87+
this.ctx = ctx;
88+
this.io = ctx.getIo();
89+
boolean printOptions = true;
90+
boolean oneLine = args.hasOption("o");
91+
List<Organization> organizations = listOrganizations();
92+
if (organizations == null) {
93+
io.errorln("Failed to fetch organizations from server.");
94+
}
95+
java.util.Optional<Organization> organization;
96+
while (true) {
97+
String slug = getOrganizationFromUser(organizations, args, printOptions, oneLine);
98+
printOptions = false;
99+
organization = organizations.stream().filter(o -> o.getSlug().equals(slug.trim().toLowerCase())).findFirst();
100+
if (!organization.isPresent()) {
101+
io.errorln("Slug doesn't match any organization.");
102+
if (oneLine) {
103+
oneLine = false;
104+
printOptions = true;
105+
}
106+
} else {
107+
break;
108+
}
109+
}
110+
if (organization.isPresent()) {
111+
io.println("Choosing organization " + organization.get().getName());
112+
} else {
113+
io.errorln("Error while choosing organization");
114+
}
115+
return OptionalToGoptional.convert(organization);
116+
}
117+
118+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package fi.helsinki.cs.tmc.cli.utils;
2+
3+
import com.google.common.base.Optional;
4+
5+
public class OptionalToGoptional {
6+
7+
public static <T> Optional<T> convert(java.util.Optional<T> convertable) {
8+
if (!convertable.isPresent()) {
9+
return Optional.absent();
10+
}
11+
return Optional.of(convertable.get());
12+
}
13+
}

0 commit comments

Comments
 (0)