Skip to content

Commit

Permalink
Merge pull request #9 from neuefische/feature_shopping_list
Browse files Browse the repository at this point in the history
feature_shopping_list
  • Loading branch information
Kinuy authored Nov 18, 2024
2 parents 9db4657 + e1d4bb9 commit 700fab7
Show file tree
Hide file tree
Showing 16 changed files with 424 additions and 5 deletions.
89 changes: 89 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: "Deploy App"

on:
push:
branches:
- main

jobs:
build-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Build Frontend
working-directory: frontend
run: |
npm install
npm run build
- uses: actions/upload-artifact@v4
with:
name: frontend-build
path: frontend/dist/

build-backend:
runs-on: ubuntu-latest
needs: build-frontend
steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: frontend-build
path: backend/src/main/resources/static

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21' # must match the version in the pom.xml
distribution: 'temurin'
cache: 'maven'

- name: Build with maven
run: mvn -B package --file backend/pom.xml

- uses: actions/upload-artifact@v4
with:
name: app.jar
path: backend/target/app.jar # must match the finalName in the pom.xml

push-to-docker-hub:
runs-on: ubuntu-latest
needs: build-backend
steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: app.jar
path: backend/target

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }} # must match the name of the Dockerhub account
password: ${{ secrets.DOCKERHUB_PASSWORD }} # must match the password of the Dockerhub account

- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ secrets.DOCKERHUB_TAG }} # Example: username/project:latest
context: .

deploy:
name: deploy-to-render
runs-on: ubuntu-latest
needs: push-to-docker-hub
environment:
name: Capstone Project # Capstone Project name
url: https://neuefische.de/ # Link to deployment
steps:
- name: Trigger Render.com Deployment
run: |
curl -X POST ${{ secrets.RENDER_DEPLOY }} #muss mit der url des Render Deployments übereinstimmen
12 changes: 12 additions & 0 deletions backend/src/main/java/springweb/backend/Client.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package springweb.backend;

import org.springframework.data.mongodb.core.mapping.Document;

import java.util.List;

@Document("clients")
public record Client(
String id,
List<GroceryProduct> shoppingList
) {
}
54 changes: 54 additions & 0 deletions backend/src/main/java/springweb/backend/ClientController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package springweb.backend;


import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.NoSuchElementException;


@RestController
@RequestMapping("/api/store/clients")
public class ClientController {

private final ClientService clientService;

public ClientController(ClientService clientService) {
this.clientService = clientService;
}

@GetMapping
public List<Client> getAllClients() {
return clientService.getAllClients();
}

@GetMapping({"{id}"})
public Client getClientByID(@PathVariable String id) {
return clientService.getClientById(id).orElseThrow(() -> new NoSuchElementException("Task not found"));
}

@PostMapping("{id}/shoppingList")
public Client addGroceryProductToClient(@PathVariable String id, @RequestBody GroceryProduct groceryProduct) {
return clientService.addGroceryProductToClient(groceryProduct, id);
}

@PostMapping
public Client addClient(@RequestBody Client client) {
return clientService.addClient(client);
}

@PutMapping("/{id}")
public Client updateTask(@PathVariable String id, @RequestBody Client clientDto) {
return clientService.updateClient(id, clientDto);
}

@DeleteMapping({"{id}"})
public void deleteClientById(@PathVariable String id) {
clientService.deleteClientById(id);
}

@DeleteMapping("{idClient}/shoppingList/{idProduct}")
public void deleteProductByIdFromClientById(@PathVariable String idClient, @PathVariable String idProduct) {
clientService.deleteProductByIdFromClientById(idClient,idProduct);
}
}
6 changes: 6 additions & 0 deletions backend/src/main/java/springweb/backend/ClientRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package springweb.backend;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface ClientRepository extends MongoRepository<Client,String> {
}
93 changes: 93 additions & 0 deletions backend/src/main/java/springweb/backend/ClientService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package springweb.backend;

import org.springframework.stereotype.Service;

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class ClientService {
private final ClientRepository clientRepository;

public ClientService(ClientRepository clientRepository) {
this.clientRepository = clientRepository;
}

public List<Client> getAllClients() {
return clientRepository.findAll();
}

public Optional<Client> getClientById(String id) {
return clientRepository.findById(id);
}

public Client addGroceryProductToClient(GroceryProduct groceryProduct, String id) {

if (clientRepository.existsById(id)) {
Client client = clientRepository.findById(id).get();
client.shoppingList().add(groceryProduct);
return clientRepository.save(client);
} else {
throw new NoSuchElementException("No Client found with Id:" + id);
}
}

public Client addClient(Client clientDto) {
Client client = new Client(clientDto.id(), clientDto.shoppingList());
return clientRepository.save(client);
}

public Client updateClient(String id, Client clientDto) {
if (clientRepository.existsById(id)) {
Client updatedClient = new Client(id, clientDto.shoppingList());
return clientRepository.save(updatedClient);
} else {
throw new NoSuchElementException("No Client found with Id:" + id);
}
}

public boolean deleteClientById(String id) {
if (clientRepository.existsById(id)) {
clientRepository.deleteById(id);
return true;
} else {
throw new NoSuchElementException("No Client found with Id:" + id);
}
}

/* WIP
public List<GroceryProduct> getAllGroceryProductsFromClient(String id) {
if (clientRepository.existsById(id)) {
return clientRepository.findById(id).get().shoppingList();
}
throw new NoSuchElementException("No Client found with Id:" + id);
}
*/

public void deleteProductByIdFromClientById(String idClient, String idProduct) {
if (clientRepository.existsById(idClient)) {
Client client = clientRepository.findById(idClient).get();
boolean productExists = client.shoppingList()
.stream()
.anyMatch(product -> product.id().equals(idProduct));
if (!client.shoppingList().isEmpty() && productExists) {

List<GroceryProduct> filteredList = client.shoppingList()
.stream()
.filter(product -> !product.id().equals(idProduct))
.collect(Collectors.toList());

client.shoppingList().clear();
client.shoppingList().addAll(filteredList);

clientRepository.save(client);
} else {
throw new NoSuchElementException("No Product found with Id:" + idProduct);
}
} else {
throw new NoSuchElementException("No Client found with Id:" + idClient);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package springweb.backend;


import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -10,7 +9,7 @@


@RestController
@RequestMapping("/api/store")
@RequestMapping("/api/store/products")
public class GroceryController {

GroceryService groceryService;
Expand Down
4 changes: 2 additions & 2 deletions backend/src/main/java/springweb/backend/GroceryService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package springweb.backend;

import lombok.NoArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -18,4 +16,6 @@ public GroceryService(GroceryRepository groceryRepository) {
public List<GroceryProduct> getAllGroceryProducts() {
return groceryRepository.findAll();
}


}
58 changes: 58 additions & 0 deletions backend/src/test/java/springweb/backend/ClientServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package springweb.backend;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

import static com.mongodb.internal.connection.tlschannel.util.Util.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

public class ClientServiceTest {

private final ClientRepository mockUserRepo = mock(ClientRepository.class);

@Test
public void GetAllClients_Test() {
// GIVEN
GroceryProduct product = new GroceryProduct("1", "Fruit", "Apple", 0.99, "apple.jpg");
List<GroceryProduct> shoppingList1 = List.of(product);
Client expectedClient1 = new Client("123", shoppingList1);

GroceryProduct product2 = new GroceryProduct("2", "Fruit", "Banana", 500, "banane.jpg");
GroceryProduct product3 = new GroceryProduct("3", "Fruit", "Kiwi", 1.80, "ps5.jpg");
List<GroceryProduct> shoppingList2 = List.of(product2, product3);
Client expectedClient2 = new Client("456", shoppingList2);

List<Client> clientList = List.of(expectedClient1, expectedClient2);

when(mockUserRepo.findAll()).thenReturn(clientList);
ClientService clientService = new ClientService(mockUserRepo);

// WHEN
List<Client> actual = clientService.getAllClients();

// THEN
verify(mockUserRepo).findAll();
assertEquals(clientList, actual);
}

@Test
public void GetClientById_Test() {
// GIVEN
GroceryProduct product = new GroceryProduct("1", "Fruit", "Apple", 0.99, "apple.jpg");
List<GroceryProduct> shoppingList = List.of(product);
Client expectedClient = new Client("123", shoppingList);

when(mockUserRepo.findById("123")).thenReturn(Optional.of(expectedClient));
ClientService clientService = new ClientService(mockUserRepo);

// WHEN
Optional<Client> result = clientService.getClientById("123");

// THEN
verify(mockUserRepo).findById("123");
assertTrue(result.isPresent());
assertEquals(expectedClient, result.get());
}
}
40 changes: 40 additions & 0 deletions frontend/public/_GroceryDB.clients.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"_id": "1",
"shoppingList": [
{
"_id": "1",
"category": "fruit",
"name": "apple",
"price": 1.5,
"image": "apple.jpg"
},
{
"_id": "2",
"category": "fruit",
"name": "banana",
"price": 1,
"image": "banane.jpg"
}
]
},
{
"_id": "2",
"shoppingList": [
{
"_id": "1",
"category": "fruit",
"name": "apple",
"price": 1.5,
"image": "apple.jpg"
},
{
"_id": "2",
"category": "fruit",
"name": "banana",
"price": 1,
"image": "banane.jpg"
}
]
}
]
Loading

0 comments on commit 700fab7

Please sign in to comment.