Skip to content

Commit

Permalink
Merge pull request #126 from KalinIvanov-l/main
Browse files Browse the repository at this point in the history
Fix SonarQube #123
  • Loading branch information
valentinacupac committed Jan 17, 2024
2 parents 4d862c3 + ba5d247 commit 40ee1da
Show file tree
Hide file tree
Showing 106 changed files with 967 additions and 555 deletions.
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Contribute to the Banking Kata (Java)

Do you find something is missing in the Banking Kata (e.g. something which you commonly do at work, but don't see it in the Kata)?
Do you find something is missing in the Banking Kata
(e.g., something that you commonly do at work, but don't see it in the Kata)?

Do you have an idea for improving something in the code base, or new functionalities?

If yes, you're welcome to contribute.

1. See the existing tickets https://github.com/valentinacupac/banking-kata-java/issues (see unassigned tickets or you can add a new ticket).
1. See the existing tickets https://github.com/valentinacupac/banking-kata-java/issues (see unassigned tickets, or you can add a new ticket).
2. If you want to "reserve" the ticket for yourself, you need to write a comment on the ticket so that I can set you as assignee (because GitHub only allows me to set assignees to people who commented).
3. Fork the project https://github.com/valentinacupac/banking-kata-java/fork and work on your fork.
4. After you've finished, make a pull request (PR), we will review and merge your changes.
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

[![CI](https://github.com/valentinacupac/banking-kata-java/actions/workflows/ci.yaml/badge.svg)](https://github.com/valentinacupac/banking-kata-java/actions/workflows/ci.yaml)

<!-- TOD0: VC: I temporarily commented this out because I'm fixing some metrics, I'll bring it back again approx next week after 7th Jun 2023-->
<!-- TOD0: VC: I temporarily commented this out because I'm fixing some metrics.
I'll bring it back again approx next week after 7th Jun 2023-->
<!--
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=valentinacupac_banking-kata-java&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=valentinacupac_banking-kata-java)
-->
Expand All @@ -23,7 +24,7 @@ We implement a Banking system with the following use cases:
- Deposit funds
- View account

We also have authentication with Keycloak - a realm with client_id and with client_credentials flow enabled.
We also have authentication with Keycloaka realm with client_id and with client_credentials flow enabled.

## Architecture

Expand All @@ -33,7 +34,7 @@ The overall architecture is split into:

The Application Core(`core`) is composed of:
- Ports (`ports`), representing an interface to the Application Core, isolating it from infrastructural concerns. There are both Driver (`driver`) ports, representing use cases; and Driven (`driven`) ports, representing gateways.
- Internals (`internal`), representing the internal implementation of the Application Core, more specifically, the implementation of the Driver (`driver`) ports. This implementation can be anything. Here we illustrate the implementation with Clean Architecture (`cleanarch`) approach and the CRUD (`crud`) approach, but other approaches are possible too. The use case tests are independent of the implementation approach; the internal implementation is thus swappable.
- Internals (`internal`), representing the internal implementation of the Application Core, more specifically, the implementation of the Driver (`driver`) ports. This implementation can be anything. Here we illustrate the implementation with Clean Architecture (`clean arch`) approach and the CRUD (`crud`) approach, but other approaches are possible too. The use case tests are independent of the implementation approach; the internal implementation is thus swappable.

The Adapter (`adapter`) layer is composed of driver adapters and driven adapters.
- Driver adapters: REST API Adapter (`adapter-restapi-*`)
Expand Down Expand Up @@ -168,7 +169,7 @@ Run code coverage (executes Jacoco):
./gradlew codeCoverage
```
To run it for specific project:
To run it for a specific project:
```shell
./gradlew core:codeCoverage
```
Expand All @@ -182,7 +183,7 @@ Run mutation testing (executes pitest):
```
<!--- TODO: Add pitest report aggregation after issue is resolved
See issue #80 Pitest report aggregation not working --->
See issue #80 Pitest report aggregation not working-->
## Viewing Reports
Expand All @@ -208,7 +209,7 @@ Then `CTRL+C` to terminate the app.
## Optional Notes
The following are for additional reading, you do not need to execute these, but you can if you wish.
The following is for additional reading, you do not need to execute these, but you can if you wish.
Environment variables are located inside the `env` folder. You can optionally choose to edit them.
Expand All @@ -223,7 +224,8 @@ To run Docker with the environment file:
docker-compose --env-file=env/.env.local up -d
```
You can run the integration tests individually, e.g. if you modified a module (in this way you avoid waiting for all of them to finish):
You can run the integration tests individually,
e.g.,if you modified a module (in this way you avoid waiting for all of them to finish):
```shell
./gradlew adapter-persistence-jpa:test
Expand All @@ -242,8 +244,8 @@ For mutation testing, the underlying call is:
```
For flyway operation from CLI:
There will be flyway tasks available in the gradle as the plugin is applied to adapter-persistence-jpa.
Tasks can be executed by the following way -
There will be flyway tasks available in the Gradle as the plugin is applied to adapter-persistence-jpa.
Tasks can be executed by the following way
```shell
./gradlew adapter-persistence-jpa:flywayInfo //will provide the schema file under flywayInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import static org.assertj.core.api.Assertions.assertThat;

public abstract class GeneratorTest<G extends Generator> {
public abstract class GeneratorTest<G extends Generator<?>> {
protected G generator;

@BeforeEach
Expand Down
42 changes: 42 additions & 0 deletions adapter-fake-auth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
18 changes: 18 additions & 0 deletions adapter-fake-auth/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
dependencies {
implementation project(':core')
implementation project(':adapter-base')

implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'

testImplementation project(':test-fixtures')
}

bootJar {
enabled = false
}

jar {
enabled = true
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.optivem.kata.banking.adapter.driver.restapi.spring.fake;
package com.optivem.kata.banking.adapter.driver.fake.auth.fake;

import com.optivem.kata.banking.adapter.driven.base.ProfileNames;
import org.springframework.context.annotation.Profile;
Expand All @@ -11,12 +11,14 @@

import java.util.ArrayList;

// TODO: VC: Probably move to separate module?
@Component
@Profile(ProfileNames.ADAPTER_AUTH_FAKE)
public class FakeAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication == null) {
throw new IllegalArgumentException("Credentials cannot be null");
}
var name = authentication.getName();
var password = authentication.getCredentials().toString();
var authorities = new ArrayList<GrantedAuthority>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.optivem.kata.banking.adapter.driver.fake.auth.fake;

import org.junit.jupiter.api.Test;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

class FakeAuthenticationProviderTest {
private final FakeAuthenticationProvider fakeAuthenticationProvider = new FakeAuthenticationProvider();

@Test
void shouldAuthenticateWithValidCredentials() {
var token = new UsernamePasswordAuthenticationToken("user", "password");
var result = fakeAuthenticationProvider.authenticate(token);
assertNotNull(result);
assertEquals("user", result.getName());
assertTrue(result.getAuthorities().isEmpty());
}

@Test
void shouldThrowExceptionWithNullCredentials() {
assertThrows(IllegalArgumentException.class, () -> fakeAuthenticationProvider.authenticate(null));
}

@Test
void shouldReturnAuthenticationWithEmptyAuthorities() {
var token = new UsernamePasswordAuthenticationToken("user", "password");
var result = fakeAuthenticationProvider.authenticate(token);
assertTrue(result.getAuthorities().isEmpty());
}

@Test
void shouldSupportUsernamePasswordAuthenticationToken() {
assertTrue(fakeAuthenticationProvider.supports(UsernamePasswordAuthenticationToken.class));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.optivem.kata.banking.adapter.driven.generation.fake;

import com.optivem.kata.banking.adapter.driven.base.GeneratorTest;
import com.optivem.kata.banking.adapter.driven.generation.fake.internal.NextElementIsNotSetupException;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class FakeAccountNumberGeneratorTest extends GeneratorTest<FakeAccountNumberGenerator> {

Expand All @@ -19,4 +24,32 @@ protected FakeAccountNumberGenerator create() {

return generator;
}

@Test
void shouldReturnsSetupValuesInOrder() {
var generator = create();

assertEquals("GB54BARC20032611545669", generator.next());
assertEquals("GB36BARC20038032622823", generator.next());
assertEquals("GB10BARC20040184197751", generator.next());
}

@Test
void shouldThrowsExceptionWhenNoMoreValues() {
var generator = create();
generator.next();
generator.next();
generator.next();

assertThrows(NextElementIsNotSetupException.class, generator::next);
}

@Test
void shouldAddsValuesToQueue() {
var generator = new FakeAccountNumberGenerator();
var newValue = "GB72BARC20041512345678";

generator.setupNext(newValue);
assertEquals(newValue, generator.next());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class FakeLongGeneratorTest {
class FakeLongGeneratorTest {
private FakeGenerator<Long> generator;

@BeforeEach
void init() {
this.generator = new FakeGenerator();
this.generator = new FakeGenerator<>();
}

@Test
Expand All @@ -22,11 +22,9 @@ void should_throw_exception_when_no_elements() {
@Test
void should_return_next_element_when_there_is_one_element() {
var expectedValue = 1001L;

generator.setupNext(expectedValue);

assertGeneratesNext(expectedValue);

assertNextThrowsException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class FakeStringGeneratorTest {
class FakeStringGeneratorTest {
private FakeGenerator<String> generator;

@BeforeEach
void init() {
this.generator = new FakeGenerator();
this.generator = new FakeGenerator<>();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.optivem.kata.banking.adapter.driven.messaging.inmemory;


import com.optivem.kata.banking.core.ports.driven.EventBus;
import com.optivem.kata.banking.core.ports.driven.events.EventDto;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;


@Component
public class ApplicationEventBus implements EventBus {

private ApplicationEventPublisher applicationEventPublisher;
private final ApplicationEventPublisher applicationEventPublisher;

public ApplicationEventBus(ApplicationEventPublisher applicationEventPublisher){
this.applicationEventPublisher = applicationEventPublisher;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import org.springframework.context.ApplicationEvent;

/**
* This class serves as the Event Object that to be puslished by ApplicationEventPublisher
* This class serves as the Event Object that to be published by ApplicationEventPublisher
*/
@Getter
public class DomainApplicationEvent<T> extends ApplicationEvent {
private T data;
private final transient T data;

public DomainApplicationEvent(T data) {
public DomainApplicationEvent(T data, T data1) {
super(data);
this.data = data1;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.optivem.kata.banking.adapter.driven.messaging.inmemory.internal;

import org.apache.logging.log4j.message.Message;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

Expand All @@ -10,21 +11,14 @@
@Component
public class UseCaseEventHandler{

private final EventQueue<DomainApplicationEvent> queue;
private final EventQueue<DomainApplicationEvent<Message>> queue;

public UseCaseEventHandler(EventQueue<DomainApplicationEvent> eventEventQueue){
public UseCaseEventHandler(EventQueue<DomainApplicationEvent<Message>> eventEventQueue){
this.queue = eventEventQueue;
}

@EventListener
public void handleEvent(DomainApplicationEvent event){
public void handleEvent(DomainApplicationEvent<Message> event){
queue.addEvent(event);

// var eventFromQueue = queue.next();
// System.out.println(eventFromQueue.getId());
// System.out.println(eventFromQueue.getEventName());
// System.out.println(eventFromQueue.getLocalDateTime());

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.optivem.kata.banking.adapter.driven.messaging.inmemory.internal;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DomainApplicationEventTest {
@Test
void shouldStoreEventData() {
var data = "Test Data";
var event = new DomainApplicationEvent<>(data, data);
assertEquals(data, event.getData());
}
}
Loading

0 comments on commit 40ee1da

Please sign in to comment.