diff --git a/pom.xml b/pom.xml index 5d76e0c..cdd484e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.0 + 3.3.1 de.uni-passau.fim.PADAS.group3 @@ -22,11 +22,6 @@ org.springframework.boot spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-thymeleaf - org.springframework.boot @@ -56,6 +51,7 @@ h2 runtime + diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java index 8a269c9..36796e3 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/Dataset.java @@ -52,7 +52,7 @@ public class Dataset { private String licence; - private static final List sortable = Arrays.asList("author", "title", "upvotes", "date"); + private static final List sortable = Arrays.asList("author", "title", "upvotes", "raiting", "date"); @ManyToOne private Category categorie; diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java index 1d1ef41..d0a00ca 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetController.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.web.bind.annotation.*; import org.springframework.data.domain.Pageable; import org.springframework.data.web.config.EnableSpringDataWebSupport; +import org.springframework.data.web.config.EnableSpringDataWebSupport.PageSerializationMode; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.data.domain.Sort; @@ -14,9 +15,9 @@ import java.util.UUID; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +@EnableSpringDataWebSupport(pageSerializationMode = PageSerializationMode.VIA_DTO) @RestController @RequestMapping("/api/v1/datasets") -@EnableSpringDataWebSupport public class DatasetController { @Autowired private DatasetService datasetService; @@ -70,7 +71,7 @@ public class DatasetController { if (datasetService.getDatasetById(id) == null) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - if (!(stars > 0 && stars < 6)) { + if (!(stars >= 0 && stars < 6)) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } datasetService.voteDataset(id, stars); diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java index 93d1388..757739e 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetService.java @@ -1,7 +1,6 @@ package de.uni_passau.fim.PADAS.group3.DataDash.Dataset; import java.time.LocalDate; -import java.util.List; import java.util.Optional; import java.util.UUID; @@ -18,44 +17,44 @@ public class DatasetService { private dataRepository datasetRepository; private CategoryRepository categoryRepository; - public DatasetService(dataRepository datasetRepository, CategoryRepository categoryRepository) { + DatasetService(dataRepository datasetRepository, CategoryRepository categoryRepository) { this.datasetRepository = datasetRepository; this.categoryRepository = categoryRepository; } - public Dataset getDatasetById(UUID id) { + Dataset getDatasetById(UUID id) { return datasetRepository.getDatasetById(id); } - public Dataset addDataset(Dataset dataset) { + Dataset addDataset(Dataset dataset) { dataset.setDate(LocalDate.now()); return datasetRepository.save(dataset); } - public void voteDataset(UUID id, int vote) { + void voteDataset(UUID id, int vote) { Dataset dataset = datasetRepository.getDatasetById(id); dataset.vote(vote); datasetRepository.save(dataset); } - public void deleteDataset(UUID id) { + void deleteDataset(UUID id) { Dataset dataset = datasetRepository.getDatasetById(id); datasetRepository.delete(dataset); } - public void upvoteDataset(UUID id) { + void upvoteDataset(UUID id) { Dataset dataset = datasetRepository.getDatasetById(id); dataset.upvote(); datasetRepository.save(dataset); } - public void downvoteDataset(UUID id) { + void downvoteDataset(UUID id) { Dataset dataset = datasetRepository.getDatasetById(id); dataset.downvote(); datasetRepository.save(dataset); } - public Page searchByOptionalCriteria(String search, String categories, String type, Pageable pageable) { + Page searchByOptionalCriteria(String search, String categories, String type, Pageable pageable) { Category category = categories.equals("%") ? null : categoryRepository.getCategoryById(UUID.fromString(categories)); Type t = type.equals("%") ? null : Type.valueOf(type); diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/dataRepository.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/dataRepository.java index c896552..b983df2 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/dataRepository.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/dataRepository.java @@ -1,9 +1,7 @@ package de.uni_passau.fim.PADAS.group3.DataDash.Dataset; -import java.util.List; import java.util.Optional; import java.util.UUID; -import java.sql.Date; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -17,32 +15,6 @@ public interface dataRepository extends JpaRepository { Dataset getDatasetById(UUID id); - List findByTitle(String title); - - List findByTitleLike(String title); - - List findByAuthorLike(String author); - - List findByType(Type type); - - List findByAuthor(String author); - - List findByAbstLike(String abst); - - List findByDescriptionLike(String description); - - List findByRaitingGreaterThan(float raiting); - - List findByVotesGreaterThan(int votes); - - List findByDateAfter(Date date); - - List findByDateBefore(Date date); - - List findByCategorie(Category categorie); - - List findByDateBetween(Date date1, Date date2); - @SuppressWarnings("null") Page findAll(Pageable pageable); diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java index 3ce13b0..f68be67 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryController.java @@ -37,8 +37,8 @@ public class CategoryController { } @ResponseStatus(HttpStatus.CREATED) @PostMapping - public void createCategory(@RequestBody CategoryDto dto) { - categoryService.addCategory(dto); + public Category createCategory(@RequestBody CategoryDto dto) { + return categoryService.addCategory(dto); } diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepository.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepository.java index acde965..38e84c6 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepository.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepository.java @@ -17,4 +17,4 @@ public interface CategoryRepository extends JpaRepository{ @SuppressWarnings("null") Optional findById(UUID id); -} +} \ No newline at end of file diff --git a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java index 3e2698f..ced75f3 100644 --- a/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java +++ b/src/main/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryService.java @@ -8,22 +8,22 @@ import java.util.UUID; public class CategoryService { private CategoryRepository categoryRepository; - public CategoryService(CategoryRepository categoryRepository) { + CategoryService(CategoryRepository categoryRepository) { this.categoryRepository = categoryRepository; } - public void addCategory(CategoryDto category) { + Category addCategory(CategoryDto category) { Category cat = new Category(category.getName()); - categoryRepository.save(cat); + return categoryRepository.save(cat); } - public List getAllCategories() { + List getAllCategories() { List tmp = categoryRepository.findAll(); List s = tmp.stream().map(CategoryDtoMapper::toDto).toList(); return s; } - public CategoryDto getCategoryById(UUID id) { + CategoryDto getCategoryById(UUID id) { Category c = categoryRepository.getCategoryById(id); if (c == null) { return null; diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 5f7c01b..7fbfc2e 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -11,13 +11,11 @@ INSERT INTO category (id, name) VALUES -- Insert sample data into dataset INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, author, description, title, url, type, licence, terms_of_use) VALUES -('2023-01-01', 4.5, 100, 120, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174100', 'Abstract 1', 'Author 1', 'Description 1', 'Title 1', 'http://example.com/1', 'API', 'MIT', 'http://url.de'), -('2023-01-02', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174101', 'Abstract 2', 'Author 2', 'Description 2', 'Title 2', 'http://example.com/2', 'DATASET', 'MIT', 'http://url.de'), -('2023-01-03', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174102', 'Abstract 3', 'Author 3', 'Description 3', 'Title 3', 'http://example.com/3', 'API', 'MIT', 'http://url.de'), -('2023-01-04', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174103', 'Abstract 4', 'Author 4', 'Description 4', 'Title 4', 'http://example.com/4', 'DATASET', 'MIT', 'http://url.de'), -('2023-01-05', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174104', 'Abstract 5', 'Author 5', 'Description 5', 'Title 5', 'http://example.com/5', 'API', 'MIT', 'http://url.de'); --- Insert 10 more sample data into dataset -INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, author, description, title, url, type, licence, terms_of_use) VALUES +('2023-01-01', 4.5, 100, 120, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174100', 'Abstract 1', 'Author 1', 'Description 1', 'Title 1', 'http://example.com/1', 'API', 'MIT', 'http://example.com'), +('2023-01-02', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174101', 'Abstract 2', 'Author 2', 'Description 2', 'Title 2', 'http://example.com/2', 'DATASET', 'MIT', 'http://example.com'), +('2023-01-03', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174102', 'Abstract 3', 'Author 3', 'Description 3', 'Title 3', 'http://example.com/3', 'API', 'MIT', 'http://example.com'), +('2023-01-04', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174103', 'Abstract 4', 'Author 4', 'Description 4', 'Title 4', 'http://example.com/4', 'DATASET', 'MIT', 'http://example.com'), +('2023-01-05', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174104', 'Abstract 5', 'Author 5', 'Description 5', 'Title 5', 'http://example.com/5', 'API', 'MIT', 'http://example.com'), ('2023-01-06', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174105', 'Abstract 6', 'Author 6', 'Description 6', 'Title 6', 'http://example.com/6', 'API', 'MIT', 'http://zip.com'), ('2023-01-07', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174106', 'Abstract 7', 'Author 7', 'Description 7', 'Title 7', 'http://example.com/7', 'DATASET', 'MIT', 'http://zip.com'), ('2023-01-08', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174107', 'Abstract 8', 'Author 8', 'Description 8', 'Title 8', 'http://example.com/8', 'API', 'MIT', 'http://zip.com'), @@ -27,4 +25,40 @@ INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, auth ('2023-09-12', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174111', 'Abstract 12', 'Author 12', 'Description 12', 'Title 12', 'http://example.com/12', 'API', 'MIT', 'http://zip.com'), ('2023-03-13', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174112', 'Abstract 13', 'Author 13', 'Description 13', 'Title 13', 'http://example.com/13', 'DATASET', 'MIT', 'http://zip.com'), ('2021-01-14', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174113', 'Abstract 14', 'Author 14', 'Description 14', 'Title 14', 'http://example.com/14', 'API', 'MIT', 'http://zip.com'), -('2024-01-15', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174114', 'Abstract 15', 'Author 15', 'Description 15', 'Title 15', 'http://example.com/15', 'DATASET', 'MIT', 'http://zip.com'); \ No newline at end of file +('2024-01-15', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174114', 'Abstract 15', 'Author 15', 'Description 15', 'Title 15', 'http://example.com/15', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-16', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174115', 'Abstract 16', 'Author 16', 'Description 16', 'Title 16', 'http://example.com/16', 'API', 'MIT', 'http://zip.com'), +('2023-01-17', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174116', 'Abstract 17', 'Author 17', 'Description 17', 'Title 17', 'http://example.com/17', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-18', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174117', 'Abstract 18', 'Author 18', 'Description 18', 'Title 18', 'http://example.com/18', 'API', 'MIT', 'http://zip.com'), +('2023-01-19', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174118', 'Abstract 19', 'Author 19', 'Description 19', 'Title 19', 'http://example.com/19', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-20', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174119', 'Abstract 20', 'Author 20', 'Description 20', 'Title 20', 'http://example.com/20', 'API', 'MIT', 'http://zip.com'), +('2023-01-21', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174120', 'Abstract 21', 'Author 21', 'Description 21', 'Title 21', 'http://example.com/21', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-22', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174121', 'Abstract 22', 'Author 22', 'Description 22', 'Title 22', 'http://example.com/22', 'API', 'MIT', 'http://zip.com'), +('2023-01-23', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174122', 'Abstract 23', 'Author 23', 'Description 23', 'Title 23', 'http://example.com/23', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-24', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174123', 'Abstract 24', 'Author 24', 'Description 24', 'Title 24', 'http://example.com/24', 'API', 'MIT', 'http://zip.com'), +('2023-01-25', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174124', 'Abstract 25', 'Author 25', 'Description 25', 'Title 25', 'http://example.com/25', 'DATASET', 'MIT', 'http://zip.com'), +('2023-01-27', 4.3, 95, 115, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174126', 'Abstract 27', 'Author 27', 'Description 27', 'Title 27', 'http://example.com/27', 'DATASET', 'GPL', 'http://zip.com'), +('2023-01-28', 4.7, 160, 180, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174127', 'Abstract 28', 'Author 28', 'Description 28', 'Title 28', 'http://example.com/28', 'API', 'GPL', 'http://zip.com'), +('2023-01-29', 4.4, 110, 130, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174128', 'Abstract 29', 'Author 29', 'Description 29', 'Title 29', 'http://example.com/29', 'DATASET', 'GPL', 'http://zip.com'), +('2023-01-30', 4.8, 190, 210, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174129', 'Abstract 30', 'Author 30', 'Description 30', 'Title 30', 'http://example.com/30', 'API', 'GPL', 'http://zip.com'), +('2023-01-31', 4.5, 100, 120, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174130', 'Abstract 31', 'Author 31', 'Description 31', 'Title 31', 'http://example.com/31', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-01', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174131', 'Abstract 32', 'Author 32', 'Description 32', 'Title 32', 'http://example.com/32', 'API', 'GPL', 'http://zip.com'), +('2023-02-02', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174132', 'Abstract 33', 'Author 33', 'Description 33', 'Title 33', 'http://example.com/33', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-03', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174133', 'Abstract 34', 'Author 34', 'Description 34', 'Title 34', 'http://example.com/34', 'API', 'GPL', 'http://zip.com'), +('2023-02-04', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174134', 'Abstract 35', 'Author 35', 'Description 35', 'Title 35', 'http://example.com/35', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-05', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174135', 'Abstract 36', 'Author 36', 'Description 36', 'Title 36', 'http://example.com/36', 'API', 'GPL', 'http://zip.com'), +('2023-02-06', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174136', 'Abstract 37', 'Author 37', 'Description 37', 'Title 37', 'http://example.com/37', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-07', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174137', 'Abstract 38', 'Author 38', 'Description 38', 'Title 38', 'http://example.com/38', 'API', 'GPL', 'http://zip.com'), +('2023-02-08', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174138', 'Abstract 39', 'Author 39', 'Description 39', 'Title 39', 'http://example.com/39', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-09', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174139', 'Abstract 40', 'Author 40', 'Description 40', 'Title 40', 'http://example.com/40', 'API', 'GPL', 'http://zip.com'); +-- Insert more sample data into dataset +INSERT INTO dataset (date, raiting, upvotes, votes, categorie_id, id, abst, author, description, title, url, type, licence, terms_of_use) VALUES +('2023-02-10', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174140', 'Abstract 41', 'Author 41', 'Description 41', 'Title 41', 'http://example.com/41', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-11', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174141', 'Abstract 42', 'Author 42', 'Description 42', 'Title 42', 'http://example.com/42', 'API', 'GPL', 'http://zip.com'), +('2023-02-12', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174002', '123e4567-e89b-12d3-a456-426614174142', 'Abstract 43', 'Author 43', 'Description 43', 'Title 43', 'http://example.com/43', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-13', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174003', '123e4567-e89b-12d3-a456-426614174143', 'Abstract 44', 'Author 44', 'Description 44', 'Title 44', 'http://example.com/44', 'API', 'GPL', 'http://zip.com'), +('2023-02-14', 4.2, 80, 100, '123e4567-e89b-12d3-a456-426614174004', '123e4567-e89b-12d3-a456-426614174144', 'Abstract 45', 'Author 45', 'Description 45', 'Title 45', 'http://example.com/45', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-15', 4.6, 120, 140, '123e4567-e89b-12d3-a456-426614174005', '123e4567-e89b-12d3-a456-426614174145', 'Abstract 46', 'Author 46', 'Description 46', 'Title 46', 'http://example.com/46', 'API', 'GPL', 'http://zip.com'), +('2023-02-16', 4.8, 180, 200, '123e4567-e89b-12d3-a456-426614174006', '123e4567-e89b-12d3-a456-426614174146', 'Abstract 47', 'Author 47', 'Description 47', 'Title 47', 'http://example.com/47', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-17', 4.3, 90, 110, '123e4567-e89b-12d3-a456-426614174007', '123e4567-e89b-12d3-a456-426614174147', 'Abstract 48', 'Author 48', 'Description 48', 'Title 48', 'http://example.com/48', 'API', 'GPL', 'http://zip.com'), +('2023-02-18', 4.7, 150, 170, '123e4567-e89b-12d3-a456-426614174000', '123e4567-e89b-12d3-a456-426614174148', 'Abstract 49', 'Author 49', 'Description 49', 'Title 49', 'http://example.com/49', 'DATASET', 'GPL', 'http://zip.com'), +('2023-02-19', 4.9, 200, 220, '123e4567-e89b-12d3-a456-426614174001', '123e4567-e89b-12d3-a456-426614174149', 'Abstract 50', 'Author 50', 'Description 50', 'Title 50', 'http://example.com/50', 'API', 'GPL', 'http://zip.com'); \ No newline at end of file diff --git a/src/main/resources/static/contentUtility.js b/src/main/resources/static/contentUtility.js index 6854b66..ceb91ac 100644 --- a/src/main/resources/static/contentUtility.js +++ b/src/main/resources/static/contentUtility.js @@ -9,7 +9,7 @@ export async function fetchQuery(fetchString, clearResults) { const data = await response.json(); parseContent(data.content, clearResults); - lastQuery.totalPages = data.totalPages; + lastQuery.totalPages = data.page.totalPages; if (clearResults) { lastQuery.currentPage = 0; } diff --git a/src/main/resources/static/details.css b/src/main/resources/static/details.css index 86bb412..92d1372 100644 --- a/src/main/resources/static/details.css +++ b/src/main/resources/static/details.css @@ -79,6 +79,17 @@ h1 { grid-column: 1 / 3; } +#rating-input { + mask-image: url("stars.svg"); + -webkit-mask-image: url("stars.svg"); + mask-size: contain; + mask-mode: alpha; + width: 5lh; + height: 1lh; + margin-inline: .5ch; + background: linear-gradient(to right, yellow 33%, black 33%); +} + #rating { color: color-mix(in oklab, var(--text-color) 80%, black); color: transparent; @@ -208,6 +219,51 @@ a { } } +#details-btns { + grid-column: 1 / 4; + justify-content: end; + gap: 1rem; + display: flex; +} + +#delete-btn { + background: #861c1c; +} + +/* button styling to be revisited */ +.btn { + padding: .5lh 1lh; + border: none; + border-radius: .5lh; + --btn-color: var(--fg-color); + background-color: var(--btn-color); + color: var(--text-color); + font-weight: bold; + font-size: 1rem; + transition: background-color 100ms, filter 200ms; + transition-timing-function: ease-out; + --drop-shadow-opacity: .5; + --drop-shadow-offset-y: 0; + --drop-shadow-blur: .25rem; + --drop-shadow: drop-shadow( + rgba(0, 0, 0, var(--drop-shadow-opacity)) + 0 var(--drop-shadow-offset-y) var(--drop-shadow-blur) + ); + filter: var(--drop-shadow); +} + +.btn:focus-visible, #is-dataset:focus-visible + #is-dataset-toggle { + outline-offset: 2px; +} + +.btn:not(:disabled):hover { + background-color: color-mix(in oklab, var(--btn-color) 80%, var(--bg-color)); + --drop-shadow-opacity: .8; + --drop-shadow-offset-y: .25rem; + --drop-shadow-blur: .4rem; +} + + #nothing-found-bg { background-position-x: calc(50% + 3cqh); } diff --git a/src/main/resources/static/details.html b/src/main/resources/static/details.html index e91405e..ff27926 100644 --- a/src/main/resources/static/details.html +++ b/src/main/resources/static/details.html @@ -24,6 +24,7 @@

Title

4 + Lorem ipsum dolor sit amet consectetur adipisicing elit. Perspiciatis recusandae laborum odio corrupti voluptas quisquam dicta, quibusdam ipsum qui exercitationem. https://example.com/dataset @@ -58,6 +59,10 @@ ipsam nobis quis.

+
+ + +
diff --git a/src/main/resources/static/details.js b/src/main/resources/static/details.js index 8c07154..1ca563f 100644 --- a/src/main/resources/static/details.js +++ b/src/main/resources/static/details.js @@ -13,6 +13,12 @@ const category = document.getElementById("category"); const license = document.getElementById("license"); const termsOfUse = document.getElementById("terms-of-use"); const fullDescription = document.getElementById("full-description"); +const backButton = document.getElementById("back-btn"); +const deleteButton = document.getElementById("delete-btn"); + +let dataset = null; +let currentRating = 0; +let isRated = false; const currentLocation = new URL(location.href); if (currentLocation.searchParams.has("id")) { @@ -24,10 +30,18 @@ if (currentLocation.searchParams.has("id")) { const dataset = new Dataset(data); const upvoteComponent = dataset.createUpvoteComponent(); + console.log(dataset.storageGet()); + debugger + if (dataset.storageGetKey("created-locally", false)) { + deleteButton.classList.remove("hidden"); + } + isRated = dataset.storageGetKey("is-rated", false) + + title.innerText = dataset.title; title.dataset.type = dataset.type.toLowerCase(); rating.value = dataset.rating; - ratingText.innerText = dataset.rating; + ratingText.innerText = parseFloat(dataset.rating).toFixed(1); shortDescription.innerText = dataset.shortDescription; url.href = dataset.url; url.innerText = dataset.url; @@ -55,3 +69,53 @@ if (currentLocation.searchParams.has("id")) { mainPage.classList.add("hidden"); notFoundPage.classList.remove("hidden"); } + +backButton.addEventListener("click", () => { + window.location.href = location.origin; +}) + +deleteButton.addEventListener("click", () => { + if (dataset != null) { + fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id, { + method: 'DELETE' + }).then(resp => { + if (resp.ok) { + window.location.href = location.origin; + } + }); + } +}); + +rating.addEventListener("mousemove", (event) => { + if (!isRated) { + let bounds = rating.getBoundingClientRect(); + currentRating = Math.round(((event.clientX - bounds.left) / bounds.width) * 5); + console.log(currentRating); + rating.value = currentRating; + } + +}); + +rating.addEventListener("mouseleave", () => { + rating.value = dataset.rating; +}); + +rating.addEventListener("click", () => { + if (!isRated) { + fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id + "/stars?stars=" + currentRating, { + method: 'PUT' + }).then(resp => { + if (resp.ok) { + dataset.storageSetKey("is-rated", true); + isRated = true; + fetch(`${currentLocation.origin}/api/v1/datasets/id/` + dataset.id) + .then(resp => resp.json()) + .then((data) => { + dataset = new Dataset(data); + ratingText.innerText = parseFloat(dataset.rating).toFixed(1); + rating.value = dataset.rating; + }); + } + }); + } +}) diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 46da537..88979c4 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -45,8 +45,8 @@ - - + + diff --git a/src/main/resources/static/main.js b/src/main/resources/static/main.js index ad98c3b..d58c423 100644 --- a/src/main/resources/static/main.js +++ b/src/main/resources/static/main.js @@ -1,4 +1,4 @@ -import { DATASET_ENDPOINT, getBaseURL } from "./constants.js"; +import { DATASET_ENDPOINT, getBaseURL } from "./constants.js" import { fetchQuery } from "./contentUtility.js"; import Dataset from "./dataset.js"; diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DataRepositoryTests.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DataRepositoryTests.java new file mode 100644 index 0000000..3a8fa41 --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DataRepositoryTests.java @@ -0,0 +1,80 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.Dataset; + +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.orm.jpa.DataJpaTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +public class DataRepositoryTests { + + @Autowired + private dataRepository dataRepository; + + @BeforeEach + private void clearDatabase() { + dataRepository.deleteAll(); + } + + @Test + public void testFindByOptionalCriteria() { + // Prepare test data + Dataset dataset = new Dataset("title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset); + + // Execute the method under test + Page result = dataRepository.findByOptionalCriteria( + Optional.of("title"), Optional.empty(), Optional.empty(), Optional.empty(), + Optional.empty(), Optional.empty(), Optional.empty(), PageRequest.of(0, 10)); + + // Assertions + assertThat(result.getContent()).hasSize(1); + assertThat(result.getContent().get(0).getTitle()).isEqualTo("title"); + } + @Test + public void searchByOptionalCriteria() { + Dataset dataset1 = new Dataset("water", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset1); + Dataset dataset = new Dataset("title1", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset); + dataset = new Dataset("title1", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset); + + Page result = dataRepository.searchByOptionalCriteria( + Optional.of("water"), Optional.empty(), PageRequest.of(0, 10)); + + assertThat(result.getContent()).hasSize(1); + assertThat(result.getContent().get(0).getTitle()).isEqualTo("water"); + } + @Test + public void searchByOptionalCriteriaMulti() { + Dataset dataset1 = new Dataset("title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset1); + Dataset dataset = new Dataset("title1", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset); + dataset = new Dataset("title1", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataRepository.save(dataset); + + Page result = dataRepository.searchByOptionalCriteria( + Optional.of("title%"), Optional.empty(), PageRequest.of(0, 10)); + + assertThat(result.getContent()).hasSize(3); + } + + @Test + public void getDatasetById() { + Dataset dataset = new Dataset("title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + dataset = dataRepository.save(dataset); + + Dataset result = dataRepository.getDatasetById(dataset.getId()); + + assertThat(result).isNotNull(); + assertThat(result.getTitle()).isEqualTo("title"); + } +} \ No newline at end of file diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java new file mode 100644 index 0000000..87bb850 --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetControllerTests.java @@ -0,0 +1,297 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.Dataset; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doAnswer; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(DatasetController.class) +public class DatasetControllerTests { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private DatasetService datasetService; + + @Autowired + private ObjectMapper objectMapper = new ObjectMapper(); + + private Dataset d = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + @Test + void getDatasetById_whenExists() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(get("/api/v1/datasets/id/" + id.toString())) + .andExpect(status().isOk()); + } + + @Test + void getDatasetById_whenNotExists() throws Exception { + UUID id = UUID.randomUUID(); + given(datasetService.getDatasetById(id)).willReturn(null); + + mockMvc.perform(get("/api/v1/datasets/id/" + id)) + .andExpect(status().isNotFound()); + } + + @Test + void createDataset() throws Exception { + Dataset dataset = d; + given(datasetService.addDataset(any(Dataset.class))).willAnswer(invocation -> invocation.getArgument(0)); + mockMvc.perform(post("/api/v1/datasets") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(dataset))) + .andExpect(status().isCreated()); + } + + @Test + void deleteDataset_whenExists() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(delete("/api/v1/datasets/id/" + id.toString())) + .andExpect(status().isOk()); + } + + @Test + void deleteDataset_whenNotExists() throws Exception { + UUID id = UUID.randomUUID(); + given(datasetService.getDatasetById(id)).willReturn(null); + + mockMvc.perform(delete("/api/v1/datasets/id/" + id)) + .andExpect(status().isNotFound()); + } + + @Test + void upvote_whenExists() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + doAnswer(invocation -> { + dataset.upvote(); // Directly modify the dataset + return null; + }).when(datasetService).upvoteDataset(id); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id.toString() + "/upvote")) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(dataset))); + + assertEquals(1, dataset.getUpvotes()); // Assuming getUpvotes() method exists and initial upvotes are 0 + } + + @Test + void upvote_whenNotExists() throws Exception { + UUID id = UUID.randomUUID(); + given(datasetService.getDatasetById(id)).willReturn(null); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/upvote")) + .andExpect(status().isNotFound()); + } + + @Test + void downvote_whenExists() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + doAnswer(invocation -> { + dataset.downvote(); // Directly modify the dataset + return null; + }).when(datasetService).downvoteDataset(id); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id.toString() + "/downvote")) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(dataset))); + + assertEquals(-1, dataset.getUpvotes()); // Assuming getDownvotes() method exists and initial downvotes are 0 + } + + @Test + void downvote_whenNotExists() throws Exception { + UUID id = UUID.randomUUID(); + given(datasetService.getDatasetById(id)).willReturn(null); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/downvote")) + .andExpect(status().isNotFound()); + } + + @Test + void postMethodName_whenExists() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + doAnswer(invocation -> { + dataset.vote(3); // Directly modify the dataset + return null; + }).when(datasetService).voteDataset(id, 3); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id.toString() + "/stars?stars=3")) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(dataset))); + + assertEquals(3, dataset.getRaiting()); // Assuming getVotes() method exists and initial votes are 0 + } + + @Test + void postMethodName_whenNotExists() throws Exception { + UUID id = UUID.randomUUID(); + given(datasetService.getDatasetById(id)).willReturn(null); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=3")) + .andExpect(status().isNotFound()); + } + + @Test + void postMethodName_whenInvalidStars() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=7")) + .andExpect(status().isBadRequest()); + } + + @Test + void postMethodName_whenInvalidStars3() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=-1")) + .andExpect(status().isBadRequest()); + } + + @Test + void postMethodName_whenInvalidStars4() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=6")) + .andExpect(status().isBadRequest()); + } + + @Test + void postMethodName_whenInvalidStars5() throws Exception { + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"); + + given(datasetService.getDatasetById(id)).willReturn(dataset); + + mockMvc.perform(put("/api/v1/datasets/id/" + id + "/stars?stars=100")) + .andExpect(status().isBadRequest()); + } + + @Test + void searchDatasets_whenExists() throws Exception { + String keyword = "title%"; + List datasets = Arrays.asList( + new Dataset("Title 1", "abst", "data", "auth", null, null, Type.API, "MIT")); + // new Dataset("Title 2", "abst", "data", "auth", null, null, Type.API, "MIT")); + + Page page = new PageImpl<>(datasets); + given(datasetService.searchByOptionalCriteria(keyword, "%", "%", + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(page); + String s = objectMapper.writeValueAsString(page); + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword)) + .andExpect(status().isOk()) + .andExpect(content().json(s)); + } + + @Test + void searchDatasets_whenNotExists() throws Exception { + String keyword = "nonexistent"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword)) + .andExpect(status().isOk()); + } + + @Test + void searchDatasets_whenInvalidSort() throws Exception { + String keyword = "data"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword + "&sort=invalid")) + .andExpect(status().isBadRequest()); + } + + @Test + void searchDatasets_whenInvalidDirection() throws Exception { + String keyword = "data"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword + "&direction=invalid")) + .andExpect(status().isBadRequest()); + } + + @Test + void searchDatasets_whenInvalidPage() throws Exception { + String keyword = "data"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword + "&page=-1")) + .andExpect(status().isBadRequest()); + } + + @Test + void searchDatasets_whenInvalidSize() throws Exception { + String keyword = "data"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword + "&size=-1")) + .andExpect(status().isBadRequest()); + } + + @Test + void searchDatasets_whenInvalidSize2() throws Exception { + String keyword = "data"; + given(datasetService.searchByOptionalCriteria(keyword, null, null, + PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "upvotes")))).willReturn(Page.empty()); + + mockMvc.perform(get("/api/v1/datasets/search?search=" + keyword + "&size=0")) + .andExpect(status().isBadRequest()); + } + +} \ No newline at end of file diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetServiceTest.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetServiceTest.java new file mode 100644 index 0000000..98e0ff4 --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/Dataset/DatasetServiceTest.java @@ -0,0 +1,123 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.Dataset; + + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.data.domain.Pageable; + +import de.uni_passau.fim.PADAS.group3.DataDash.category.Category; +import de.uni_passau.fim.PADAS.group3.DataDash.category.CategoryRepository; + +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +class DatasetServiceTest { + + @Mock + private dataRepository datasetRepository; + @Mock + private CategoryRepository categoryRepository; + + @InjectMocks + private DatasetService datasetService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testGetDatasetById() { // Test for getDatasetById method + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset(); + when(datasetRepository.getDatasetById(id)).thenReturn(dataset); + assertEquals(dataset, datasetService.getDatasetById(id)); + } + + @Test + void testAddDataset() { // Test for addDataset method + Dataset dataset = new Dataset(); + when(datasetRepository.save(dataset)).thenReturn(dataset); + assertEquals(dataset, datasetService.addDataset(dataset)); + } + + @Test + void testVoteDataset() { // Test for voteDataset method + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset(); + when(datasetRepository.getDatasetById(id)).thenReturn(dataset); + datasetService.voteDataset(id, 5); + verify(datasetRepository).save(dataset); + assertEquals(1, dataset.getVotes()); + assertEquals(5, dataset.getRaiting()); + } + + @Test + void testDeleteDataset() { // Test for deleteDataset method + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset(); + when(datasetRepository.getDatasetById(id)).thenReturn(dataset); + datasetService.deleteDataset(id); + verify(datasetRepository).delete(dataset); + } + + @Test + void testUpvoteDataset() { // Test for upvoteDataset method + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset(); + when(datasetRepository.getDatasetById(id)).thenReturn(dataset); + datasetService.upvoteDataset(id); + verify(datasetRepository).save(dataset); + assertEquals(1, dataset.getUpvotes()); + } + + @Test + void testDownvoteDataset() { // Test for downvoteDataset method + UUID id = UUID.randomUUID(); + Dataset dataset = new Dataset(); + when(datasetRepository.getDatasetById(id)).thenReturn(dataset); + datasetService.downvoteDataset(id); + verify(datasetRepository).save(dataset); + assertEquals(-1, dataset.getUpvotes()); + } + + + + @Test + void testSearchByOptionalCriteria() { // Test for searchByOptionalCriteria method + String search = "search"; + Type type = Type.DATASET; + Pageable pageable = PageRequest.of(0, 10); + List datasets = Arrays.asList(new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"), new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT")); + PageImpl s = new PageImpl(datasets); + given(datasetRepository.searchByOptionalCriteria(Optional.ofNullable(search), Optional.ofNullable(type),pageable)).willReturn(s); + assertEquals(s.getContent(), datasetService.searchByOptionalCriteria(search, "%",type.toString(), pageable).getContent()); + } + + @Test + void testSearchByOptionalCriteriaWithCategory() { // Test for searchByOptionalCriteria method + String search = "search"; + Type type = Type.DATASET; + String category = UUID.randomUUID().toString(); + Category cat = new Category(); + Pageable pageable = PageRequest.of(0, 10); + List datasets = Arrays.asList(new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT"), new Dataset("Title", "abst", "desc", "auth", null, null, Type.API, "MIT")); + PageImpl s = new PageImpl(datasets); + given(categoryRepository.getCategoryById(UUID.fromString(category))).willReturn(cat); + given(datasetRepository.searchByOptionalCriteriaWithCategory(Optional.ofNullable(search), cat ,Optional.ofNullable(type),pageable)).willReturn(s); + assertEquals(s.getContent(), datasetService.searchByOptionalCriteria(search, category,type.toString(), pageable).getContent()); + } + + // Additional tests for other methods can be added following the same pattern. +} \ No newline at end of file diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryControllerTest.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryControllerTest.java new file mode 100644 index 0000000..d977563 --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryControllerTest.java @@ -0,0 +1,75 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.category; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Arrays; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@WebMvcTest(CategoryController.class) +public class CategoryControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private CategoryService categoryService; + + @Autowired + private ObjectMapper objectMapper; + + Category category = new Category("yeet"); + + @Test + public void testGetAllCategories() throws Exception { + CategoryDto category1 = CategoryDtoMapper.toDto(category); + CategoryDto category2 = CategoryDtoMapper.toDto(category); + given(categoryService.getAllCategories()).willReturn(Arrays.asList(category1, category2)); + + mockMvc.perform(get("/api/v1/categories")) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(Arrays.asList(category1, category2)))); + } + + @Test + public void testFetchCategoryByIdFound() throws Exception { + UUID id = UUID.randomUUID(); + CategoryDto category = CategoryDtoMapper.toDto(this.category); + given(categoryService.getCategoryById(id)).willReturn(category); + + mockMvc.perform(get("/api/v1/categories/id/{id}", id)) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(category))); + } + + @Test + public void testFetchCategoryByIdNotFound() throws Exception { + UUID id = UUID.randomUUID(); + given(categoryService.getCategoryById(id)).willReturn(null); + + mockMvc.perform(get("/api/v1/categories/id/{id}", id)) + .andExpect(status().isNotFound()); + } + + @Test + public void testCreateCategory() throws Exception { + CategoryDto categoryDto = CategoryDtoMapper.toDto(category); + mockMvc.perform(post("/api/v1/categories") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(categoryDto))) + .andExpect(status().isCreated()); + // Verify that the service method was called once + verify(categoryService).addCategory(any(CategoryDto.class)); + } +} \ No newline at end of file diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepositoryTests.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepositoryTests.java new file mode 100644 index 0000000..2330d6c --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryRepositoryTests.java @@ -0,0 +1,56 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.category; + +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.orm.jpa.DataJpaTest; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +public class CategoryRepositoryTests { + + @Autowired + private CategoryRepository categoryRepository; + + private Category savedCategory; + + @BeforeEach + public void setup() { + // Setup data for each test + Category category = new Category(); + category.setName("Test Category"); + // Assuming Category class has a setName method and an ID that is auto-generated + savedCategory = categoryRepository.save(category); + } + + @Test + public void whenFindById_thenReturnCategory() { + Optional foundCategory = categoryRepository.findById(savedCategory.getId()); + assertThat(foundCategory).isPresent(); + assertThat(foundCategory.get().getId()).isEqualTo(savedCategory.getId()); + } + + @Test + public void whenFindByName_thenReturnCategoryList() { + List categories = categoryRepository.findByName("Test Category"); + assertThat(categories).hasSize(1); + assertThat(categories.get(0).getName()).isEqualTo("Test Category"); + } + + @Test + public void whenFindAll_thenReturnAllCategories() { + List categories = categoryRepository.findAll(); + assertThat(categories).isNotEmpty(); + } + + @Test + public void whenGetCategoryById_thenReturnCategory() { + Category foundCategory = categoryRepository.getCategoryById(savedCategory.getId()); + assertThat(foundCategory).isNotNull(); + assertThat(foundCategory.getId()).isEqualTo(savedCategory.getId()); + } +} \ No newline at end of file diff --git a/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryServiceTest.java b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryServiceTest.java new file mode 100644 index 0000000..a06d189 --- /dev/null +++ b/src/test/java/de/uni_passau/fim/PADAS/group3/DataDash/category/CategoryServiceTest.java @@ -0,0 +1,68 @@ +package de.uni_passau.fim.PADAS.group3.DataDash.category; + +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class CategoryServiceTest { + + @Mock + private CategoryRepository categoryRepository; + + @InjectMocks + private CategoryService categoryService; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void testAddCategory() { + CategoryDto categoryDto = new CategoryDto("Test Category", UUID.randomUUID()); + categoryService.addCategory(categoryDto); + + verify(categoryRepository, times(1)).save(any(Category.class)); + } + + @Test + public void testGetAllCategories() { + when(categoryRepository.findAll()).thenReturn(Arrays.asList(new Category("Category 1"), new Category("Category 2"))); + + List categories = categoryService.getAllCategories(); + + assertNotNull(categories); + assertEquals(2, categories.size()); + } + + @Test + public void testGetCategoryByIdFound() { + UUID id = UUID.randomUUID(); + Category category = new Category("Test Category"); + when(categoryRepository.getCategoryById(id)).thenReturn(category); + + CategoryDto result = categoryService.getCategoryById(id); + + assertNotNull(result); + assertEquals("Test Category", result.getName()); + } + + @Test + public void testGetCategoryByIdNotFound() { + UUID id = UUID.randomUUID(); + when(categoryRepository.getCategoryById(id)).thenReturn(null); + + CategoryDto result = categoryService.getCategoryById(id); + + assertNull(result); + } +} \ No newline at end of file