done GA12
This commit is contained in:
parent
a22f8bb6cb
commit
2077cf0741
83 changed files with 368115 additions and 0 deletions
78
.gitignore
vendored
78
.gitignore
vendored
|
@ -2,3 +2,81 @@ artist.txt
|
|||
.idea/
|
||||
target/
|
||||
*.iml
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
|
|
2
assignment-w13/.gitignore
vendored
Normal file
2
assignment-w13/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
testing-tools/
|
||||
**/testing-tools/
|
Binary file not shown.
1
assignment-w13/comments-api/file.txt
Normal file
1
assignment-w13/comments-api/file.txt
Normal file
|
@ -0,0 +1 @@
|
|||
comments.repository.MapCriticsRepository
|
61
assignment-w13/comments-api/ga12.md
Normal file
61
assignment-w13/comments-api/ga12.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
title: Software Quality & Testing -- Graded Assignment 12
|
||||
author: Claudio Maggioni
|
||||
geometry: margin=2.5cm,bottom=3cm
|
||||
---
|
||||
|
||||
# Exercise 1 and 2
|
||||
|
||||
The necessary edits have been performed in the test class `src/test/java/comments/CommentsTest.java`.
|
||||
|
||||
# Exercise 3
|
||||
|
||||
I use EvoMaster to generate test cases and find the bug in the source code. I run
|
||||
EvoMaster with the following command from the project root folder `comments-api`:
|
||||
|
||||
```shell
|
||||
java --add-opens java.base/java.net=ALL-UNNAMED \
|
||||
--add-opens java.base/java.util=ALL-UNNAMED \
|
||||
-jar ./testing-tools/evomaster.jar --blackBox true \
|
||||
--bbSwaggerUrl http://localhost:8080/docs/swagger.yaml \
|
||||
--outputFormat JAVA_JUNIT_4 --maxTime 5m
|
||||
```
|
||||
|
||||
EvoMaster correctly finds a bug in the `GET /comments` route,
|
||||
causing a 500 error when the `limit` query parameter is set to `0` and
|
||||
the `offset` query parameter is not given.
|
||||
|
||||
The generated tests are included in the directory `src/test/java/em`.
|
||||
|
||||
# Exercise 4
|
||||
|
||||
To run Randoop without a test oracle I run the following commands from the project root folder:
|
||||
|
||||
```shell
|
||||
echo "comments.repository.MapCriticsRepository" > file.txt
|
||||
java -classpath testing-tools/randoop-4.3.2/randoop-all-4.3.2.jar:target/classes \
|
||||
randoop.main.Main gentests --classlist=file.txt --time-limit=120
|
||||
```
|
||||
|
||||
To run Randoop with the test oracle `jdoctor-oracles.json` I run the following commands from the project root folder:
|
||||
|
||||
```shell
|
||||
echo "comments.repository.MapCriticsRepository" > file.txt
|
||||
java -classpath testing-tools/randoop-4.3.2/randoop-all-4.3.2.jar:target/classes \
|
||||
randoop.main.Main gentests --classlist=file.txt --time-limit=120 \
|
||||
--specifications=jdoctor-oracles.json
|
||||
```
|
||||
|
||||
The generated tests without the oracle are included in the directory `src/test/java/randoopWithoutOracle`, while
|
||||
the ones generated with the oracle are included in the directory `src/test/java/randoopWithOracle`.
|
||||
|
||||
The difference between the test generated with or without oracle lies in the assertions over the
|
||||
`MapCriticsRepository.addComment(Comment)` method. The oracle file `jdoctor-oracles.json` specifies that this method
|
||||
should throw a `IllegalArgumentException` when its parameter is null. In the tests without oracle, this exception throwing
|
||||
is treated as a possible bug and tests that cause it are placed in `ErrorTest*` classes since by not expecting
|
||||
the exception they fail. However, in the tests generated with oracles the exception throwing behaviour is correctly tested,
|
||||
thus making tests fail when no exception is thrown and the parameter is indeed `null`. Even with the oracle the tests still fail,
|
||||
since a `NullPointerException` is thrown instead of the `IllegalArgumentException` expected in the oracle (and the
|
||||
documentation of the method), thus uncovering a new bug in `MapCriticsRepository`.
|
||||
|
||||
|
BIN
assignment-w13/comments-api/ga12.pdf
Normal file
BIN
assignment-w13/comments-api/ga12.pdf
Normal file
Binary file not shown.
30
assignment-w13/comments-api/jdoctor-oracles.json
Normal file
30
assignment-w13/comments-api/jdoctor-oracles.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
[
|
||||
{
|
||||
"operation": {
|
||||
"classname": "comments.repository.MapCriticsRepository",
|
||||
"name": "addComment",
|
||||
"parameterTypes": [
|
||||
"comments.model.Comment"
|
||||
]
|
||||
},
|
||||
"identifiers": {
|
||||
"parameters": [
|
||||
"c"
|
||||
],
|
||||
"receiverName": "receiverObjectID",
|
||||
"returnName": "methodResultID"
|
||||
},
|
||||
"throws": [
|
||||
{
|
||||
"exception": "java.lang.IllegalArgumentException",
|
||||
"description": "@throws java.lang.IllegalArgumentException the comment is null.",
|
||||
"guard": {
|
||||
"condition": "c==null",
|
||||
"description": "the comment is null."
|
||||
}
|
||||
}
|
||||
],
|
||||
"post": [],
|
||||
"pre": []
|
||||
}
|
||||
]
|
95
assignment-w13/comments-api/pom.xml
Normal file
95
assignment-w13/comments-api/pom.xml
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>es.us.aiss</groupId>
|
||||
<artifactId>comments</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.9.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-core-spi</artifactId>
|
||||
<version>4.6.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-spring-boot-starter</artifactId>
|
||||
<version>4.8.0.Final</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>2.4.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Test Dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>4.3.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atlassian.oai</groupId>
|
||||
<artifactId>swagger-request-validator-core</artifactId>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atlassian.oai</groupId>
|
||||
<artifactId>swagger-request-validator-restassured</artifactId>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.minidev</groupId>
|
||||
<artifactId>json-smart</artifactId>
|
||||
<version>2.4.7</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.evosuite</groupId>
|
||||
<artifactId>evosuite</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/testing-tools/evosuite-1.2.0.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.evomaster</groupId>
|
||||
<artifactId>evomaster-client-java-controller</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
package comments.main;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package comments.main;
|
||||
|
||||
import comments.resources.CommentResource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.core.Application;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
@ApplicationPath("/api")
|
||||
public class CommentsAPIApplication extends Application {
|
||||
|
||||
private Set<Object> singletons = new HashSet<Object>();
|
||||
private Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
public CommentsAPIApplication() {
|
||||
singletons.add(CommentResource.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> getSingletons() {
|
||||
return singletons;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package comments.model;
|
||||
|
||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
|
||||
public class Comment {
|
||||
private String id;
|
||||
private String userName;
|
||||
private String text;
|
||||
private String date;
|
||||
private String type; // Enum: Review, Request, Complain
|
||||
|
||||
public Comment(){}
|
||||
|
||||
public Comment(String userName, String text, String date, String type) {
|
||||
this.userName=userName;
|
||||
this.text = text;
|
||||
this.date = date;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Comment(String id, String userName, String text, String date, String type) {
|
||||
this.id=id;
|
||||
this.userName=userName;
|
||||
this.text = text;
|
||||
this.date = date;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 29 * hash + Objects.hashCode(this.id);
|
||||
hash = 29 * hash + Objects.hashCode(this.userName);
|
||||
hash = 29 * hash + Objects.hashCode(this.text);
|
||||
hash = 29 * hash + Objects.hashCode(this.date);
|
||||
hash = 29 * hash + Objects.hashCode(this.type);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Comment other = (Comment) obj;
|
||||
if (!Objects.equals(this.id, other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.userName, other.userName)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.text, other.text)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.date, other.date)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.type, other.type)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package comments.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Profile {
|
||||
private String userName;
|
||||
private List<Comment> comments;
|
||||
|
||||
public Profile(){}
|
||||
|
||||
public Profile(String userName){
|
||||
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> list){
|
||||
this.comments=list;
|
||||
}
|
||||
|
||||
public Comment getComment(String id){
|
||||
if (comments==null)
|
||||
return null;
|
||||
|
||||
Comment comment =null;
|
||||
for(Comment c: comments)
|
||||
if (c.getId().equals(id))
|
||||
{
|
||||
comment=c;
|
||||
break;
|
||||
}
|
||||
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void addComment(Comment c){
|
||||
if(comments==null){
|
||||
comments = new ArrayList<Comment>();
|
||||
}
|
||||
comments.add(c);
|
||||
}
|
||||
|
||||
public void deleteComment(Comment c){
|
||||
comments.remove(c);
|
||||
}
|
||||
|
||||
public void deleteComment(String id){
|
||||
Comment c = getComment(id);
|
||||
if(c != null){
|
||||
comments.remove(c);
|
||||
}
|
||||
|
||||
}
|
||||
public void deleteAllComments(){
|
||||
comments.removeAll(comments);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package comments.repository;
|
||||
|
||||
import comments.model.Comment;
|
||||
import comments.model.Profile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface CriticsRepository {
|
||||
|
||||
/*Comments*/
|
||||
public List<Comment> getAllComments();
|
||||
public void addComment(Comment c);
|
||||
public Comment getComment(String commentId);
|
||||
public void deleteComment(String commentId);
|
||||
public void updateComment(Comment c);
|
||||
|
||||
/*Profiles*/
|
||||
public List<Profile> getAllProfiles();
|
||||
public void addProfile(Profile p);
|
||||
public Profile getProfile(String username);
|
||||
public void deleteProfile(String username);
|
||||
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
package comments.repository;
|
||||
|
||||
import comments.model.Comment;
|
||||
import comments.model.Profile;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
public class MapCriticsRepository implements CriticsRepository {
|
||||
|
||||
Map<String, Comment> commentMap;
|
||||
Map<String, Profile> profileMap;
|
||||
private static MapCriticsRepository instance = null;
|
||||
private int index = 0;
|
||||
|
||||
public static MapCriticsRepository getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new MapCriticsRepository();
|
||||
instance.init();
|
||||
}
|
||||
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
private void init() {
|
||||
commentMap = new HashMap<String, Comment>();
|
||||
profileMap = new HashMap<String, Profile>();
|
||||
|
||||
// Create Comments
|
||||
Comment c1 = new Comment();
|
||||
c1.setUserName("johnSmith");
|
||||
c1.setText("Great book!");
|
||||
c1.setType("Review");
|
||||
c1.setDate("2017-02-16T20:44:53.950");
|
||||
addComment(c1);
|
||||
|
||||
Comment c2 = new Comment();
|
||||
c2.setUserName("johnSmith");
|
||||
c2.setText("Original product but the quality is too low for the price");
|
||||
c2.setType("Review");
|
||||
c2.setDate("2017-06-16T20:44:53.950");
|
||||
addComment(c2);
|
||||
|
||||
Comment c3 = new Comment();
|
||||
c3.setUserName("johnSmith");
|
||||
c3.setText("The product was delivered three days after the expected date.");
|
||||
c3.setType("Complain");
|
||||
c3.setDate("2017-06-16T20:48:53.950");
|
||||
addComment(c3);
|
||||
|
||||
Comment c4 = new Comment();
|
||||
c4.setUserName("oliviaClark");
|
||||
c4.setText("I would love to see this product in pocket size");
|
||||
c4.setType("Request");
|
||||
c4.setDate("2015-01-16T20:44:53.950");
|
||||
addComment(c4);
|
||||
|
||||
Comment c5 = new Comment();
|
||||
c5.setUserName("oliviaClark");
|
||||
c5.setText("Please, give me a call before the delivery");
|
||||
c5.setType("Request");
|
||||
c5.setDate("2015-06-22T20:12:45.950");
|
||||
addComment(c5);
|
||||
|
||||
Comment c6 = new Comment();
|
||||
c6.setUserName("gloriaCavanni");
|
||||
c6.setText("I love the color and the shape of the cover");
|
||||
c6.setType("Review");
|
||||
c6.setDate("2020-11-16T20:44:53.950");
|
||||
addComment(c6);
|
||||
|
||||
Comment c7 = new Comment();
|
||||
c7.setUserName("markSpecter");
|
||||
c7.setText("Adding a sim card slot would be a winner point!");
|
||||
c7.setType("Request");
|
||||
c7.setDate("1998-01-16T20:44:53.950");
|
||||
addComment(c7);
|
||||
|
||||
Comment c8 = new Comment();
|
||||
c8.setUserName("markSpecter");
|
||||
c8.setText("Nice product, my kids love it.");
|
||||
c8.setType("Review");
|
||||
c8.setDate("2013-04-16T20:44:53.950");
|
||||
addComment(c8);
|
||||
|
||||
Comment c9 = new Comment();
|
||||
c9.setUserName("markSpecter");
|
||||
c9.setText("Too bad, too late.");
|
||||
c9.setType("Complain");
|
||||
c9.setDate("2018-04-16T20:44:53.950");
|
||||
addComment(c9);
|
||||
|
||||
Comment c10 = new Comment();
|
||||
c10.setUserName("markSpecter");
|
||||
c10.setText("It is bigger than it look in the image, but it does the work");
|
||||
c10.setType("Review");
|
||||
c10.setDate("2019-08-02T12:31:53.950");
|
||||
addComment(c10);
|
||||
|
||||
Comment c11 = new Comment();
|
||||
c11.setUserName("testUser");
|
||||
c11.setText("This is a test comment");
|
||||
c11.setType(null);
|
||||
c11.setDate("2020-08-02T12:31:53.950");
|
||||
addComment(c11);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Comments */
|
||||
|
||||
@Override
|
||||
public List<Comment> getAllComments() {
|
||||
List<Comment> comments = new ArrayList<Comment>(commentMap.values());
|
||||
return comments;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws IllegalArgumentException if the comment is null
|
||||
*/
|
||||
@Override
|
||||
public void addComment(Comment c) {
|
||||
String id = "c" + index++;
|
||||
if (profileMap.containsKey(c.getUserName())) {
|
||||
profileMap.get(c.getUserName()).addComment(c);
|
||||
} else {
|
||||
Profile p = new Profile();
|
||||
p.setUserName(c.getUserName());
|
||||
p.addComment(c);
|
||||
profileMap.put(p.getUserName(), p);
|
||||
}
|
||||
c.setId(id);
|
||||
if (c.getDate() != null) {
|
||||
c.setDate(c.getDate());
|
||||
} else {
|
||||
c.setDate(LocalDateTime.now().toString());
|
||||
}
|
||||
|
||||
commentMap.put(id, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comment getComment(String commentId) {
|
||||
return commentMap.get(commentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteComment(String commentId) {
|
||||
|
||||
Comment c = commentMap.get(commentId);
|
||||
commentMap.remove(commentId);
|
||||
profileMap.get(c.getUserName()).deleteComment(commentId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateComment(Comment c) {
|
||||
Comment comment = commentMap.get(c.getId());
|
||||
comment.setText(c.getText());
|
||||
if (c.getDate() != null) {
|
||||
c.setDate(c.getDate());
|
||||
} else {
|
||||
c.setDate(LocalDateTime.now().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Profiles */
|
||||
|
||||
@Override
|
||||
public List<Profile> getAllProfiles() {
|
||||
List<Profile> profiles = new ArrayList<Profile>(profileMap.values());
|
||||
return profiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProfile(Profile p) {
|
||||
p.setComments(new ArrayList<Comment>());
|
||||
for (Comment e : commentMap.values()) {
|
||||
if (e.getUserName().equals(p.getUserName())) {
|
||||
p.addComment(e);
|
||||
}
|
||||
}
|
||||
profileMap.put(p.getUserName(), p);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Profile getProfile(String userName) {
|
||||
return profileMap.get(userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProfile(String userName) {
|
||||
Set<Comment> comments = new HashSet<Comment>(commentMap.values());
|
||||
for (Comment e : comments) {
|
||||
if (e.getUserName().equals(userName)) {
|
||||
deleteComment(e.getId());
|
||||
}
|
||||
}
|
||||
profileMap.remove(userName);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package comments.resources;
|
||||
|
||||
import comments.model.Comment;
|
||||
import comments.repository.CriticsRepository;
|
||||
import comments.repository.MapCriticsRepository;
|
||||
//import org.jboss.resteasy.spi.BadRequestException;
|
||||
//import org.jboss.resteasy.spi.NotFoundException;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.*;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/comments")
|
||||
public class CommentResource {
|
||||
|
||||
public static CommentResource _instance = null;
|
||||
CriticsRepository repository;
|
||||
|
||||
private CommentResource() {
|
||||
repository = MapCriticsRepository.getInstance();
|
||||
}
|
||||
|
||||
public static CommentResource getInstance() {
|
||||
if (_instance == null) {
|
||||
_instance = new CommentResource();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void order(List<Comment> list) {
|
||||
// Comparator<Comment> c = Comparator.comparing(x -> x.getDate());
|
||||
Collections.sort(list, new ComparatorDateComment());
|
||||
}
|
||||
|
||||
public List<Comment> length(List<Comment> list, Integer index) {
|
||||
List<Comment> sublist = list.subList(0, index);
|
||||
return sublist;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
public Response getAll(@QueryParam("contains") String word, @QueryParam("type") String type, @QueryParam("order") String order,
|
||||
@QueryParam("offset") String offset, @QueryParam("limit") String limit) {
|
||||
|
||||
if(type != null && !type.equals("Review") && !type.equals("Request") && !type.equals("Complain") && !type.equals("All"))
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("type must be one of Review, Request, Complain or All").build();
|
||||
// return Response.status(400).build();
|
||||
|
||||
if(order != null && !order.equals("date") && !order.equals("-date") && !order.equals("+date"))
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("order must be one of date, -date or +date").build();
|
||||
// return Response.status(400).build();
|
||||
|
||||
|
||||
List<Comment> comments = new ArrayList<Comment>();
|
||||
Comment c = null;
|
||||
Iterator<Comment> iterator = repository.getAllComments().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
c = iterator.next();
|
||||
if (wordFilter(c, word) && typeFilter(c, type)) {
|
||||
comments.add(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (order != null && (order.equals("date") || order.equals("+date"))) {
|
||||
|
||||
Collections.sort(comments, new ComparatorDateComment());
|
||||
}
|
||||
if (order != null && order.equals("-date")) {
|
||||
Collections.sort(comments, new ComparatorDateCommentReversed());
|
||||
}
|
||||
Integer off = 0;
|
||||
Integer lim = comments.size();
|
||||
|
||||
|
||||
if (offset != null) {
|
||||
try {
|
||||
off = new Integer(offset);
|
||||
if (off < 0 || off > comments.size()) {
|
||||
off = 0;
|
||||
}
|
||||
} catch(NumberFormatException e) {
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("The offset must be a number").build();
|
||||
}
|
||||
}
|
||||
if (limit != null) {
|
||||
try {
|
||||
lim = new Integer(limit);
|
||||
if (lim < 0 || lim + off > comments.size()) {
|
||||
lim = comments.size();
|
||||
} else {
|
||||
lim--;
|
||||
}
|
||||
} catch(NumberFormatException e) {
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("The limit must be a number").build();
|
||||
}
|
||||
|
||||
}
|
||||
comments = comments.subList(off, lim + off > comments.size() ? lim : lim + off);
|
||||
|
||||
return Response.ok(comments).build();
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@Produces("application/json")
|
||||
public Response getComment(@PathParam("id") String commentId) {
|
||||
Comment comment = repository.getComment(commentId);
|
||||
if (comment == null) {
|
||||
return Response.status(404).type(MediaType.TEXT_PLAIN).entity("The comment with id" + commentId + " was not found").type(MediaType.TEXT_PLAIN).build();
|
||||
// return Response.status(404).build();
|
||||
}
|
||||
return Response.ok(comment).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@Produces("application/json")
|
||||
public Response deleteComment(@PathParam("id") String commentId) {
|
||||
Comment comment = repository.getComment(commentId);
|
||||
if (comment == null) {
|
||||
return Response.status(404).type(MediaType.TEXT_PLAIN).entity("The comment with id" + commentId + " was not found").build();
|
||||
// return Response.status(404).build();
|
||||
}
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response addComment(@Context UriInfo uriInfo, Comment c) {
|
||||
if (!validateBodyPost(c)) {
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("You must complete the username and text fields").build();
|
||||
// return Response.status(400).build();
|
||||
}
|
||||
|
||||
if (c.getType() != null && !(c.getType().equals("Review") || c.getType().equals("Request") || c.getType().equals("Complain"))) {
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("Invalid value for type parameter").build();
|
||||
// return Response.status(400).build();
|
||||
}
|
||||
|
||||
repository.addComment(c);
|
||||
UriBuilder ub = uriInfo.getAbsolutePathBuilder().path(this.getClass(), "getComment");
|
||||
URI uri = ub.build(c.getId());
|
||||
ResponseBuilder resp = Response.created(uri);
|
||||
resp.entity(c);
|
||||
return resp.build();
|
||||
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response updateComment(Comment c) {
|
||||
if(!validateBodyPut(c))
|
||||
return Response.status(400).type(MediaType.TEXT_PLAIN).entity("You must complete all fields").build();
|
||||
// return Response.status(400).build();
|
||||
Comment oldComment = repository.getComment(c.getId());
|
||||
if (oldComment == null) {
|
||||
return Response.status(404).type(MediaType.TEXT_PLAIN).entity("The comment with id " + c.getId() + " was not found").build();
|
||||
// return Response.status(404).build();
|
||||
}
|
||||
repository.updateComment(c);
|
||||
return Response.ok(repository.getComment(c.getId())).build();
|
||||
}
|
||||
|
||||
private boolean validateBodyPost(Comment c) {
|
||||
return c != null && c.getUserName() != null && !c.getUserName().equals("") && c.getText() != null
|
||||
&& !c.getText().equals("") && !(c.getType() != null && !c.getType().equals("Review")
|
||||
&& !c.getType().equals("Request") && !c.getType().equals("Complain"));
|
||||
}
|
||||
|
||||
private boolean validateBodyPut(Comment c) {
|
||||
return c != null && c.getId() != null && !c.getId().equals("") && c.getUserName() != null
|
||||
&& !c.getUserName().equals("") && c.getText() != null && !c.getText().equals("")
|
||||
&& c.getId() != null && !c.getId().equals("") && c.getDate() != null && !c.getDate().equals("")
|
||||
&& c.getType() != null && (c.getType().equals("Review") || c.getType().equals("Request")
|
||||
|| c.getType().equals("Complain"));
|
||||
}
|
||||
|
||||
// Returns true if the comment include word, or if the word is null or empty.
|
||||
private boolean wordFilter(Comment c, String word) {
|
||||
return (word == null || word.equals("") || c.getText().contains(word));
|
||||
}
|
||||
|
||||
// Returns true if the comment matches the input type.
|
||||
private boolean typeFilter(Comment c, String type) {
|
||||
// return (type == null || type.equals("") || type.equals("All") || c.getType().equals(type));
|
||||
return type == null || type.equals("") || type.equals("All") || (c.getType() != null && c.getType().equals(type));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package comments.resources;
|
||||
|
||||
import comments.model.Comment;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ComparatorDateComment implements Comparator<Comment> {
|
||||
|
||||
@Override
|
||||
public int compare(Comment c1, Comment c2) {
|
||||
// TODO Auto-generated method stub
|
||||
return c1.getDate().compareTo(c2.getDate());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package comments.resources;
|
||||
|
||||
import comments.model.Comment;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ComparatorDateCommentReversed implements Comparator<Comment> {
|
||||
|
||||
@Override
|
||||
public int compare(Comment c1, Comment c2) {
|
||||
// TODO Auto-generated method stub
|
||||
return c2.getDate().compareTo(c1.getDate());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
resteasy:
|
||||
jaxrs:
|
||||
app:
|
||||
registration: property
|
||||
classes: comments.main.CommentsAPIApplication
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include:
|
||||
- health
|
||||
- shutdown
|
||||
endpoint:
|
||||
shutdown:
|
||||
enabled: true
|
||||
logging:
|
||||
level:
|
||||
org:
|
||||
springframework: info
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<threadsafe>true</threadsafe>
|
||||
<sessions-enabled>false</sessions-enabled>
|
||||
<runtime>java8</runtime>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
</system-properties>
|
||||
|
||||
</appengine-web-app>
|
|
@ -0,0 +1,4 @@
|
|||
# https://cloud.google.com/appengine/docs/standard/java/logs/
|
||||
|
||||
# Set the default logging level for all loggers to WARNING
|
||||
.level = WARNING
|
33
assignment-w13/comments-api/src/main/webapp/WEB-INF/web.xml
Normal file
33
assignment-w13/comments-api/src/main/webapp/WEB-INF/web.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<!-- All REST resources will be prefixed by /api -->
|
||||
<context-param>
|
||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||
<param-value>/api</param-value>
|
||||
</context-param>
|
||||
|
||||
<!-- Servlets -->
|
||||
<servlet>
|
||||
<servlet-name>Resteasy</servlet-name>
|
||||
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
|
||||
<init-param>
|
||||
<param-name>javax.ws.rs.Application</param-name>
|
||||
<param-value>comments.main.CommentsAPIApplication</param-value>
|
||||
</init-param>
|
||||
</servlet>
|
||||
|
||||
<!-- Servlet mappings -->
|
||||
<!-- All calls to /api/xxx will be sent to the resteasy servlet -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>Resteasy</servlet-name>
|
||||
<url-pattern>/api/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
Binary file not shown.
After Width: | Height: | Size: 665 B |
Binary file not shown.
After Width: | Height: | Size: 628 B |
60
assignment-w13/comments-api/src/main/webapp/docs/index.html
Normal file
60
assignment-w13/comments-api/src/main/webapp/docs/index.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "http://localhost:8080/docs/swagger.yaml",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
271
assignment-w13/comments-api/src/main/webapp/docs/swagger.yaml
Normal file
271
assignment-w13/comments-api/src/main/webapp/docs/swagger.yaml
Normal file
|
@ -0,0 +1,271 @@
|
|||
---
|
||||
swagger: "2.0"
|
||||
info:
|
||||
description: This is a simple Comments API
|
||||
version: 1.0.0
|
||||
title: Comments
|
||||
host: localhost:8080
|
||||
basePath: /api
|
||||
tags:
|
||||
- name: Comments
|
||||
description: music comments
|
||||
schemes:
|
||||
- http
|
||||
paths:
|
||||
/comments:
|
||||
get:
|
||||
operationId: getComments
|
||||
tags:
|
||||
- Comments
|
||||
summary: searches comments
|
||||
description: |
|
||||
Returns all comments made by all users
|
||||
produces:
|
||||
- application/json
|
||||
- text/html;charset=utf-8
|
||||
parameters:
|
||||
- in: query
|
||||
name: contains
|
||||
description: filter comments by string
|
||||
required: false
|
||||
type: string
|
||||
- in: query
|
||||
name: type
|
||||
description: filter comments by type
|
||||
required: false
|
||||
type: string
|
||||
enum:
|
||||
- Review
|
||||
- Request
|
||||
- Complain
|
||||
- All
|
||||
- in: query
|
||||
name: order
|
||||
description: order comments by date
|
||||
required: false
|
||||
type: string
|
||||
enum:
|
||||
- date
|
||||
- +date
|
||||
- -date
|
||||
- in: query
|
||||
name: offset
|
||||
description: get comments from certain position
|
||||
required: false
|
||||
type: integer
|
||||
- in: query
|
||||
name: limit
|
||||
description: limit comments retrieved
|
||||
required: false
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: searchs all comments
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/CommentReturned'
|
||||
"400":
|
||||
description: bad input parameter
|
||||
post:
|
||||
operationId: postComment
|
||||
tags:
|
||||
- Comments
|
||||
summary: adds a comment
|
||||
description: Adds a comment to the system
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
- text/html;charset=utf-8
|
||||
parameters:
|
||||
- in: body
|
||||
name: comment
|
||||
description: comment to add
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/CommentPost'
|
||||
responses:
|
||||
"201":
|
||||
description: comment created
|
||||
schema:
|
||||
$ref: '#/definitions/CommentReturned'
|
||||
"400":
|
||||
description: invalid input, object invalid
|
||||
put:
|
||||
operationId: putComment
|
||||
tags:
|
||||
- Comments
|
||||
summary: adds a comment
|
||||
description: Adds an comment to the system
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
- text/html;charset=utf-8
|
||||
parameters:
|
||||
- in: body
|
||||
name: comment
|
||||
description: Comment to update
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/CommentPut'
|
||||
responses:
|
||||
"200":
|
||||
description: comment created
|
||||
schema:
|
||||
$ref: '#/definitions/CommentReturned'
|
||||
"400":
|
||||
description: invalid input, object invalid
|
||||
"404":
|
||||
description: not found
|
||||
/comments/{id}:
|
||||
get:
|
||||
operationId: getComment
|
||||
tags:
|
||||
- Comments
|
||||
summary: search a comments
|
||||
description: "Returns a comment \n"
|
||||
produces:
|
||||
- application/json
|
||||
- text/html;charset=utf-8
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: id of the comment
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: search results matching criteria
|
||||
schema:
|
||||
$ref: '#/definitions/CommentReturned'
|
||||
"404":
|
||||
description: not found
|
||||
delete:
|
||||
operationId: deleteComment
|
||||
tags:
|
||||
- Comments
|
||||
summary: delete a comment
|
||||
description: "Deletes a comment \n"
|
||||
produces:
|
||||