Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit b18ebff

Browse files
authored
FF-88 Feature/system health cucumber (#8)
* Implemented SystemHealth.feature with Steps. * implemented SystemHealth Cucumber Steps. Commented not implemented ucs.
1 parent b155df0 commit b18ebff

File tree

8 files changed

+322
-229
lines changed

8 files changed

+322
-229
lines changed

src/main/java/de/filefighter/rest/configuration/PrepareDataBaseProd.java renamed to src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.filefighter.rest.configuration;
22

3+
import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository;
4+
import de.filefighter.rest.domain.token.data.persistance.AccessTokenRepository;
35
import de.filefighter.rest.domain.user.data.persistance.UserEntity;
46
import de.filefighter.rest.domain.user.data.persistance.UserRepository;
57
import org.slf4j.Logger;
@@ -10,18 +12,30 @@
1012
import org.springframework.context.annotation.Profile;
1113

1214
@Configuration
13-
@Profile("prod")
14-
public class PrepareDataBaseProd {
15+
public class PrepareDataBase {
1516

16-
private static final Logger LOG = LoggerFactory.getLogger(PrepareDataBaseProd.class);
17+
private static final Logger LOG = LoggerFactory.getLogger(PrepareDataBase.class);
1718

1819
@Bean
19-
CommandLineRunner initUserDataBase(UserRepository repository) {
20+
CommandLineRunner cleanDataBase(UserRepository userRepository, FileSystemRepository fileSystemRepository, AccessTokenRepository accessTokenRepository) {
2021

2122
//Note: when the admin user changes his/her password, a new refreshToken will be created.
2223
return args -> {
2324
LOG.info("Starting with clean user collection.");
24-
repository.deleteAll();
25+
userRepository.deleteAll();
26+
LOG.info("Starting with clean fileSystem collection.");
27+
fileSystemRepository.deleteAll();
28+
LOG.info("Starting with clean accessToken collection.");
29+
accessTokenRepository.deleteAll();
30+
};
31+
}
32+
33+
@Bean
34+
@Profile("prod")
35+
CommandLineRunner initUserDataBase(UserRepository repository) {
36+
37+
//Note: when the admin user changes his/her password, a new refreshToken will be created.
38+
return args -> {
2539
LOG.info("Preloading default admin user: " + repository.save(UserEntity
2640
.builder()
2741
.userId(0L)

src/test/java/de/filefighter/rest/RestApplicationIntegrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package de.filefighter.rest;
22

3-
import de.filefighter.rest.configuration.RestConfiguration;
43
import de.filefighter.rest.domain.filesystem.rest.FileSystemRestController;
54
import de.filefighter.rest.domain.health.rest.SystemHealthRestController;
65
import de.filefighter.rest.domain.permission.rest.PermissionRestController;
76
import de.filefighter.rest.domain.user.rest.UserRestController;
87
import org.jetbrains.annotations.NotNull;
8+
import org.junit.jupiter.api.AfterAll;
99
import org.junit.jupiter.api.Test;
1010
import org.springframework.beans.factory.annotation.Autowired;
1111
import org.springframework.boot.test.context.SpringBootTest;

src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package de.filefighter.rest.cucumber;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.JsonNode;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
36
import de.filefighter.rest.RestApplicationIntegrationTest;
4-
import de.filefighter.rest.configuration.RestConfiguration;
57
import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity;
68
import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository;
79
import de.filefighter.rest.domain.token.data.persistance.AccessTokenEntity;
@@ -12,24 +14,29 @@
1214
import io.cucumber.java.en.Given;
1315
import io.cucumber.java.en.Then;
1416
import org.springframework.beans.factory.annotation.Autowired;
15-
import org.springframework.http.HttpMethod;
1617

18+
import java.io.IOException;
1719
import java.time.Instant;
1820
import java.util.Arrays;
21+
import java.util.UUID;
1922

2023
import static de.filefighter.rest.domain.token.business.AccessTokenBusinessService.ACCESS_TOKEN_DURATION_IN_SECONDS;
24+
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
import static org.junit.jupiter.api.Assertions.assertTrue;
2126

2227
public class CommonCucumberSteps extends RestApplicationIntegrationTest {
2328

2429
private final UserRepository userRepository;
2530
private final AccessTokenRepository accessTokenRepository;
2631
private final FileSystemRepository fileSystemRepository;
32+
private final ObjectMapper objectMapper;
2733

2834
@Autowired
2935
public CommonCucumberSteps(UserRepository userRepository, AccessTokenRepository accessTokenRepository, FileSystemRepository fileSystemRepository) {
3036
this.userRepository = userRepository;
3137
this.accessTokenRepository = accessTokenRepository;
3238
this.fileSystemRepository = fileSystemRepository;
39+
this.objectMapper = new ObjectMapper();
3340
}
3441

3542
@Given("database is empty")
@@ -68,53 +75,94 @@ public void userWithIdExistsAndHasUsernamePasswordAndRefreshToken(long userId, S
6875
.build());
6976
}
7077

71-
// file / folder
78+
// This step almost needs a unit test.
7279
@Given("{string} exists with id {long} and path {string}")
73-
public void existsWithIdAndPath(String fileOrFolder, long fsItemId, String path) {
74-
if(fileOrFolder.equals("file")){
75-
//TODO: split into folders and files.
76-
String[] names = path.split("/");
77-
System.out.println(Arrays.toString(names));
78-
79-
fileSystemRepository.save(FileSystemEntity
80-
.builder()
81-
.isFile(true)
82-
.id(fsItemId)
83-
.create());
84-
}else if(fileOrFolder.equals("folder")){
85-
fileSystemRepository.save(FileSystemEntity
86-
.builder()
87-
.isFile(false)
88-
.id(fsItemId)
89-
.path(path)
90-
.create());
91-
}else{
92-
throw new IllegalArgumentException("Found not valid string for FileOrFolder in Steps file.");
80+
public void fileOrFolderExistsWithIdAndPath(String fileOrFolder, long fsItemId, String path) {
81+
String[] names = path.split("/");
82+
StringBuilder completeFilePath = new StringBuilder("/");
83+
84+
System.out.println(Arrays.toString(names));
85+
86+
// create root dir.
87+
fileSystemRepository.save(FileSystemEntity
88+
.builder()
89+
.isFile(false)
90+
.path(completeFilePath.toString())
91+
.create());
92+
93+
94+
// create all files and folders.
95+
for (int i = 0; i < names.length; i++) {
96+
if (!names[i].isEmpty() && !names[i].isBlank()) {
97+
boolean isLastOne = i == names.length - 1;
98+
if(!isLastOne){
99+
//is obviously a folder.
100+
completeFilePath.append(names[i]).append("/");
101+
fileSystemRepository.save(FileSystemEntity
102+
.builder()
103+
.isFile(false)
104+
.path(completeFilePath.toString())
105+
.create());
106+
System.out.println("folder: "+completeFilePath.toString());
107+
}else{
108+
System.out.println("last one: "+names[i]);
109+
if (fileOrFolder.equals("file")) {
110+
fileSystemRepository.save(FileSystemEntity
111+
.builder()
112+
.isFile(true)
113+
.id(fsItemId)
114+
.create());
115+
} else if (fileOrFolder.equals("folder")) {
116+
completeFilePath.append(names[i]).append("/");
117+
fileSystemRepository.save(FileSystemEntity
118+
.builder()
119+
.isFile(false)
120+
.id(fsItemId)
121+
.path(completeFilePath.toString())
122+
.create());
123+
} else {
124+
throw new IllegalArgumentException("Found not valid string for FileOrFolder in Steps file.");
125+
}
126+
}
127+
}
93128
}
94129
}
95130

96131
@And("user {long} is owner of file or folder with id {long}")
97132
public void userIsOwnerOfFileOrFolderWithId(long userId, long fsItemId) {
98133
FileSystemEntity fileSystemEntity = fileSystemRepository.findById(fsItemId);
99-
if(null == fileSystemEntity){
100-
throw new IllegalArgumentException("FileSystemEntity was null.");
101-
}
102134

103135
fileSystemEntity.setCreatedByUserId(userId);
104136
fileSystemRepository.save(fileSystemEntity);
105137
}
106138

107139
//key: value for json type response.
108140
@Then("response contains key {string} and value {string}")
109-
public void responseContainsKeyAndValue(String key, String value) {
141+
public void responseContainsKeyAndValue(String key, String value) throws JsonProcessingException {
142+
JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
143+
String actualValue = rootNode.get(key).asText();
144+
145+
assertEquals(value, actualValue);
110146
}
111147

112148
@And("response contains the user with id {long}")
113-
public void responseContainsTheUserWithId(long userId) {
149+
public void responseContainsTheUserWithId(long userId) throws JsonProcessingException {
150+
JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
151+
long actualValue = rootNode.get("userId").asLong();
152+
153+
assertEquals(userId, actualValue);
114154
}
115155

116156
@Then("response status code is {int}")
117-
public void responseStatusCodeIs(int httpStatusCode) {
157+
public void responseStatusCodeIs(int httpStatusCode) throws IOException {
158+
assertEquals(httpStatusCode, latestResponse.getTheResponse().getRawStatusCode());
118159
}
119160

161+
@And("response contains key {string} and value of at least {int}")
162+
public void responseContainsKeyAndValueOfAtLeast(String key, int value) throws JsonProcessingException {
163+
JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
164+
int actualValue = rootNode.get(key).asInt();
165+
166+
assertTrue(actualValue >= value);
167+
}
120168
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package de.filefighter.rest.cucumber;
2+
3+
import de.filefighter.rest.RestApplicationIntegrationTest;
4+
import io.cucumber.java.en.When;
5+
import org.springframework.http.HttpMethod;
6+
7+
public class SystemHealthSteps extends RestApplicationIntegrationTest {
8+
@When("the systemHealth endpoint is requested")
9+
public void theSystemHealthEndpointIsRequested() {
10+
executeRestApiCall(HttpMethod.GET, "health/");
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Feature: SystemHealth
2+
As a user
3+
I want to be able to get status information about the state of the application.
4+
5+
Background:
6+
Given database is empty
7+
8+
Scenario: SystemHealth is requested without users in db
9+
When the systemHealth endpoint is requested
10+
Then response contains key "userCount" and value "0"
11+
And response contains key "uptimeInSeconds" and value of at least 1
12+
13+
Scenario: SystemHealth is requested with users in db
14+
Given user 1234 exists
15+
And user 3214 exists
16+
When the systemHealth endpoint is requested
17+
Then response contains key "userCount" and value "2"
18+
And response contains key "uptimeInSeconds" and value of at least 1
19+
Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
1-
Feature: User Authorization
2-
As a user
3-
I want to be able to log in with username and password, as well as verify my identity
4-
when using the endpoints.
5-
6-
Background:
7-
Given database is empty
8-
And user with id 1234 exists and has username "user", password "secure_password" and refreshToken "token"
9-
10-
Scenario: Successful login with username and password.
11-
When user requests login with username "user" and password "secure_password"
12-
Then response contains key "refreshToken" and value "token"
13-
And response status code is 200
14-
And response contains the user with id 1234
15-
16-
Scenario: Failed login with username and password.
17-
When user requests login with username "user" and password "wrong_password"
18-
Then response contains key "message" and value "User not authenticated."
19-
And response contains key "status" and value "denied"
20-
And response status code is 401
21-
22-
Scenario: Successful retrieval of accessToken with refreshToken.
23-
When user requests accessToken with refreshToken "token" and userId 1234
24-
Then response contains key "userId" and value "1234"
25-
And response contains valid accessToken
26-
And response status code is 200
27-
28-
Scenario: Failed retrieval of accessToken with wrong refreshToken.
29-
When user requests accessToken with refreshToken "not_the_token" and userId 1234
30-
Then response contains key "message" and value "User not authenticated."
31-
And response contains key "status" and value "denied"
32-
And response status code is 401
33-
34-
Scenario: Successful UserInfo request with valid accessToken.
35-
Given user 1234 has access token "accessToken"
36-
When user requests userInfo with accessToken "accessToken" and userId 1234
37-
Then response contains the user with id 1234
38-
And response status code is 200
39-
40-
Scenario: Failed UserInfo request with invalid accessToken.
41-
When user requests userInfo with accessToken "notTheAccessToken" and userId 1234
42-
Then response contains key "message" and value "User not authenticated."
43-
And response contains key "status" and value "denied"
44-
And response status code is 401
1+
#Feature: User Authorization
2+
# As a user
3+
# I want to be able to log in with username and password, as well as verify my identity
4+
# when using the endpoints.
5+
#
6+
#Background:
7+
# Given database is empty
8+
# And user with id 1234 exists and has username "user", password "secure_password" and refreshToken "token"
9+
#
10+
#Scenario: Successful login with username and password.
11+
# When user requests login with username "user" and password "secure_password"
12+
# Then response contains key "refreshToken" and value "token"
13+
# And response status code is 200
14+
# And response contains the user with id 1234
15+
#
16+
#Scenario: Failed login with username and password.
17+
# When user requests login with username "user" and password "wrong_password"
18+
# Then response contains key "message" and value "User not authenticated."
19+
# And response contains key "status" and value "denied"
20+
# And response status code is 401
21+
#
22+
#Scenario: Successful retrieval of accessToken with refreshToken.
23+
# When user requests accessToken with refreshToken "token" and userId 1234
24+
# Then response contains key "userId" and value "1234"
25+
# And response contains valid accessToken
26+
# And response status code is 200
27+
#
28+
#Scenario: Failed retrieval of accessToken with wrong refreshToken.
29+
# When user requests accessToken with refreshToken "not_the_token" and userId 1234
30+
# Then response contains key "message" and value "User not authenticated."
31+
# And response contains key "status" and value "denied"
32+
# And response status code is 401
33+
#
34+
#Scenario: Successful UserInfo request with valid accessToken.
35+
# Given user 1234 has access token "accessToken"
36+
# When user requests userInfo with accessToken "accessToken" and userId 1234
37+
# Then response contains the user with id 1234
38+
# And response status code is 200
39+
#
40+
#Scenario: Failed UserInfo request with invalid accessToken.
41+
# When user requests userInfo with accessToken "notTheAccessToken" and userId 1234
42+
# Then response contains key "message" and value "User not authenticated."
43+
# And response contains key "status" and value "denied"
44+
# And response status code is 401

0 commit comments

Comments
 (0)