Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#896 test for tax module #909

Merged
merged 29 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a696df7
Integration test for tax class repository
hnd14 Aug 16, 2024
91a51f9
Integration test for tax rate repository
hnd14 Aug 16, 2024
285716b
Fixing typo
hnd14 Aug 16, 2024
2eb79f1
Integration test tax class controller
hnd14 Aug 16, 2024
7bbe39f
Add more integration test tax class controller
hnd14 Aug 16, 2024
df957dd
Integration test for tax rate controller
hnd14 Aug 18, 2024
9e7ecff
Merge branch 'main' into test-tax
hnd14 Aug 19, 2024
90d33d2
Merge branch 'main' into test-tax
hnd14 Aug 19, 2024
f9964fb
Add test for some service
hnd14 Aug 19, 2024
6e68354
Add test for some more cases
hnd14 Aug 19, 2024
54009d3
Merge branch 'main' into test-tax
hnd14 Aug 19, 2024
30153af
Refactor: Sonarcloud fix
hnd14 Aug 19, 2024
413179f
Refactor: Rename file to be read by maven
hnd14 Aug 19, 2024
ff9cc35
fix: fix bugs in test
hnd14 Aug 19, 2024
46d59f7
fix: fix bugs in test
hnd14 Aug 19, 2024
ef38dcb
fix: fix bugs in test
hnd14 Aug 19, 2024
90ee0b2
refactor: refactor code
hnd14 Aug 19, 2024
6951d23
Merge branch 'main' into test-tax
hnd14 Aug 20, 2024
5e04692
refactor: refactor common test dependencies into parent pom
hnd14 Aug 20, 2024
7e21859
Refactor: refactor redundancy
hnd14 Aug 20, 2024
d658c21
Add DataJpaTest for repository
hnd14 Aug 22, 2024
e0fc0d6
refactor:moved integration test files to separate directory
hnd14 Aug 22, 2024
f37dec3
refactor: modify pom file to run integration tests from different dir…
hnd14 Aug 22, 2024
cb29812
refactor: Add integration test resources
hnd14 Aug 22, 2024
84abb3a
Additional unit test for service
hnd14 Aug 23, 2024
7828e7e
Remove redundant tests
hnd14 Aug 23, 2024
6009e09
Refactor: Rename api calls to variables to avoid hard coding problem
hnd14 Aug 23, 2024
2f40ebb
update ci for integration test
thiennn Aug 26, 2024
1b4f6b4
just report test on file name with TEST
thiennn Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions tax/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,39 @@
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.instancio</groupId>
<artifactId>instancio-junit</artifactId>
<version>${instancio-junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dasniko</groupId>
<artifactId>testcontainers-keycloak</artifactId>
<version>${testcontainers-keycloak.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
hnd14 marked this conversation as resolved.
Show resolved Hide resolved
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
public class TaxClassController {
private final TaxClassService taxClassService;

public TaxClassController(TaxClassService taxClassServic) {
this.taxClassService = taxClassServic;
public TaxClassController(TaxClassService taxClassService) {
this.taxClassService = taxClassService;
}

@GetMapping("/paging")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.yas.tax.integration.config;

import dasniko.testcontainers.keycloak.KeycloakContainer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.testcontainers.containers.PostgreSQLContainer;

@TestConfiguration
public class IntegrationTestConfiguration {

@Bean(destroyMethod = "stop")
public PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16")
.withReuse(true);
}

@Bean(destroyMethod = "stop")
public KeycloakContainer keycloakContainer(DynamicPropertyRegistry registry) {
KeycloakContainer keycloak = new KeycloakContainer()
.withRealmImportFiles("/test-realm.json")
.withReuse(true);

registry.add("spring.security.oauth2.resourceserver.jwt.issuer-uri",
() -> keycloak.getAuthServerUrl() + "/realms/quarkus");
registry.add("spring.security.oauth2.resourceserver.jwt.jwk-set-uri",
() -> keycloak.getAuthServerUrl() + "/realms/quarkus/protocol/openid-connect/certs");
return keycloak;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.yas.tax.integration.controller;

import static io.restassured.RestAssured.given;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.MediaType;
import org.testcontainers.shaded.com.google.common.net.HttpHeaders;

public class AbstractControllerIT {

@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
protected String authServerUrl;

@LocalServerPort
private int port;

protected RequestSpecification getRequestSpecification() {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
return new RequestSpecBuilder()
.setPort(port)
.addHeader(
HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE
)
.build();
}

protected String getAccessToken(String username, String password) {
return given()
.contentType("application/x-www-form-urlencoded")
.formParams(Map.of(
"username", username,
"password", password,
"scope", "openid",
"grant_type", "password",
"client_id", "quarkus-service",
"client_secret", "secret"
))
.post(authServerUrl + "/protocol/openid-connect/token")
.then().assertThat().statusCode(200)
.extract().path("access_token");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
package com.yas.tax.integration.controller;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.instancio.Select.field;

import com.yas.tax.constants.PageableConstant;
import com.yas.tax.integration.config.IntegrationTestConfiguration;
import com.yas.tax.model.TaxClass;
import com.yas.tax.repository.TaxClassRepository;
import com.yas.tax.repository.TaxRateRepository;
import com.yas.tax.viewmodel.taxclass.TaxClassPostVm;
import io.restassured.RestAssured;
import java.util.Optional;
import org.instancio.Instancio;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.testcontainers.junit.jupiter.Testcontainers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
@Import(IntegrationTestConfiguration.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class TaxClassControllerIntegrationTest extends AbstractControllerIT{
@Autowired
TaxClassRepository taxClassRepository;
@Autowired
TaxRateRepository taxRateRepository;

TaxClass taxClass;

@BeforeEach
void setUp(){
taxClass = taxClassRepository.save(Instancio.of(TaxClass.class).create());
}

@AfterEach
void tearDown() {
taxRateRepository.deleteAll();
taxClassRepository.deleteAll();
}

@Test
void test_findAllTaxClass_shouldReturnData_whenGivenAccessToken(){
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.when()
.get("/v1/backoffice/tax-classes")
.then()
.statusCode(HttpStatus.OK.value())
.body(".", hasSize(1))
.log().ifValidationFails();
}

@Test
void test_findAllTaxClass_shouldReturn401_whenNotGivenAccessToken(){
RestAssured.given(getRequestSpecification())
.when()
.get("/v1/backoffice/tax-classes")
.then()
.statusCode(HttpStatus.UNAUTHORIZED.value())
.log().ifValidationFails();
}

@Test
void test_getTaxClass_shouldReturn401_whenUnauthenticated(){
RestAssured.given(getRequestSpecification())
.when()
.get("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.UNAUTHORIZED.value())
.log().ifValidationFails();
}

@Test
void test_getTaxClass_shouldReturnData_whenGivenAccessTokenAndCorrectId(){
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.when()
.get("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.OK.value())
.body("name", equalTo(taxClass.getName()))
.log().ifValidationFails();
}

@Test
void test_getTaxClass_shouldReturn404_whenGivenAccessTokenAndWrongId(){
long wrongId = taxClass.getId() - 1;
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.when()
.get("/v1/backoffice/tax-classes/"+wrongId)
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.log().ifValidationFails();
}

@Test
void test_getPagedTaxClass_shouldReturn401_whenNotGivenAccessToken(){
RestAssured.given(getRequestSpecification())
.when()
.get("/v1/backoffice/tax-classes/paging")
.then()
.statusCode(HttpStatus.UNAUTHORIZED.value())
.log().ifValidationFails();
}

@Test
void test_getPagedTaxClass_shouldReturnData_whenGivenAccessToken(){
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.when()
.get("/v1/backoffice/tax-classes/paging")
.then()
.statusCode(HttpStatus.OK.value())
.body("pageNo", equalTo(Integer.valueOf(PageableConstant.DEFAULT_PAGE_NUMBER)))
.body("pageSize", equalTo(Integer.valueOf(PageableConstant.DEFAULT_PAGE_SIZE)))
.body("totalElements", equalTo(1))
.body("totalPages", equalTo(1))
.log().ifValidationFails();
}

@Test
void test_createTaxClass_shouldReturn403_whenNotGivenAccessToken() {
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class).create();
RestAssured.given(getRequestSpecification())
.body(body)
.post("/v1/backoffice/tax-classes")
.then()
.statusCode(HttpStatus.FORBIDDEN.value())
.log().ifValidationFails();
}

@Test
void test_createTaxClass_shouldReturnCreated_whenGivenAccessToken() {
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class).create();
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.body(body)
.post("/v1/backoffice/tax-classes")
.then()
.statusCode(HttpStatus.CREATED.value())
.log().ifValidationFails();
}

@Test
void test_createTaxClass_shouldReturn400_whenGivenAccessTokenAndExistedName() {
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class)
.set(field("name"), taxClass.getName()).create();
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.body(body)
.post("/v1/backoffice/tax-classes")
.then()
.statusCode(HttpStatus.BAD_REQUEST.value())
.log().ifValidationFails();

assertThat(taxClassRepository.existsByName(body.name())).isTrue();
}

@Test
void test_updateTaxClass_shouldReturn403_whenGivenAccessTokenAndExistedName() {
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class)
.set(field("name"), taxClass.getName()).create();

RestAssured.given(getRequestSpecification())
.body(body)
.put("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.FORBIDDEN.value())
.log().ifValidationFails();
}

@Test
void test_updateTaxClass_shouldReturn204_whenGivenAccessTokenAndCorrectId() {
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class)
.set(field("name"), taxClass.getName()).create();

RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.body(body)
.put("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.NO_CONTENT.value())
.log().ifValidationFails();

Optional<TaxClass> result = taxClassRepository.findById(taxClass.getId());
assertThat(result).isPresent();
assertThat(result.get().getName()).isEqualTo(body.name());
}

@Test
void test_updateTaxClass_shouldReturn404_whenGivenAccessTokenAndWrongId() {
long wrongId = taxClass.getId() - 1;
TaxClassPostVm body = Instancio.of(TaxClassPostVm.class)
.set(field("name"), taxClass.getName()).create();

RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.body(body)
.put("/v1/backoffice/tax-classes/"+wrongId)
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.log().ifValidationFails();
}

@Test
void test_updateTaxClass_shouldReturn400_whenGivenAccessTokenAndDuplicateName() {
TaxClass anotherClass = taxClassRepository.save(Instancio.of(TaxClass.class).create());

TaxClassPostVm body = Instancio.of(TaxClassPostVm.class)
.set(field("name"), taxClass.getName()).create();

RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.body(body)
.put("/v1/backoffice/tax-classes/"+anotherClass.getId().toString())
.then()
.statusCode(HttpStatus.BAD_REQUEST.value())
.log().ifValidationFails();
}

@Test
void test_deleteTaxClass_shouldReturn403_whenGivenAccessTokenAndExistedName() {
RestAssured.given(getRequestSpecification())
.delete("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.FORBIDDEN.value())
.log().ifValidationFails();
}

@Test
void test_deleteTaxClass_shouldReturn204_whenGivenAccessTokenAndCorrectId() {
RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.delete("/v1/backoffice/tax-classes/"+taxClass.getId().toString())
.then()
.statusCode(HttpStatus.NO_CONTENT.value())
.log().ifValidationFails();
}

@Test
void test_deleteTaxClass_shouldReturn404_whenGivenAccessTokenAndWrongId() {
long wrongId = taxClass.getId() - 1;

RestAssured.given(getRequestSpecification())
.auth().oauth2(getAccessToken("admin", "admin"))
.delete("/v1/backoffice/tax-classes/"+wrongId)
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.log().ifValidationFails();
}
}
Loading
Loading