From 1580497500162ebb9c1c67485ac768225d5a2449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Wed, 4 Oct 2023 15:11:40 +0200 Subject: [PATCH 1/8] feat: conforminit test init --- test/README.md | 4 ++++ test/check-service-conformity.feature | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 test/README.md create mode 100644 test/check-service-conformity.feature diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..a1d4cdd --- /dev/null +++ b/test/README.md @@ -0,0 +1,4 @@ +## Test Script + +### Test Script to check the good behavior of each service implementation. + diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature new file mode 100644 index 0000000..27652f8 --- /dev/null +++ b/test/check-service-conformity.feature @@ -0,0 +1,16 @@ +Feature: + +Scenario: + * url 'http://localhost:8080/' + * path 'healthcheck' + * method head + +Scenario: + * url 'http://localhost:8080/' + * path 'healthcheck' + * method head + +Scenario: + * url 'http://localhost:8080/' + * path 'api/accounts' + * method post \ No newline at end of file From e604dbb16a1f7eef796936d77265ee98ff823986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Thu, 5 Oct 2023 12:26:35 +0200 Subject: [PATCH 2/8] feat: 1 scenario of conformity --- test/check-service-conformity.feature | 68 +++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature index 27652f8..ed0395b 100644 --- a/test/check-service-conformity.feature +++ b/test/check-service-conformity.feature @@ -1,16 +1,68 @@ Feature: -Scenario: +Background: + * def now = function(){ return java.lang.System.currentTimeMillis() } + * def account_name = 'Conformity-' + now() * url 'http://localhost:8080/' - * path 'healthcheck' - * method head Scenario: - * url 'http://localhost:8080/' * path 'healthcheck' * method head -Scenario: - * url 'http://localhost:8080/' - * path 'api/accounts' - * method post \ No newline at end of file +Scenario: Simple Conformity Scenario + Given path 'api/accounts' + And header Content-Type = 'application/json' + And request { login: #(account_name) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, login: #(account_name), creation_date: #notnull } + Then def account_id = response.id + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And def list_name = 'List-' + now() + And request { name: #(list_name) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, name: #(list_name), creation_date: #notnull , account_id: #(account_id)} + Then def list_id = response.id + Given path 'api/lists',list_id,'tasks' + And header Content-Type = 'application/json' + And def task_name = 'Task-' + now() + And def task_description = 'Description-' + now() + And request { name: #(task_name), description: #(task_description) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, name: #(task_name), description: #(task_description) , creation_date: #notnull , list_id: #(list_id)} + Then def task_id = response.id + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And param page = 0 + When method get + Then match [200, 201, 204] contains responseStatus + Then match response[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then match response[0].tasks[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Given path 'api/stats' + And header Content-Type = 'application/json' + When method get + Then match [200, 201, 204] contains responseStatus + Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) + Then match sub_result[0] == { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } + Given path 'api/lists',list_id,'tasks' + And header Content-Type = 'application/json' + And def task_name_2 = 'Task-' + now() + And def task_description_2 = 'Description-' + now() + And request { name: #(task_name_2), description: #(task_description_2) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, name: #(task_name_2), description: #(task_description_2) , creation_date: #notnull , list_id: #(list_id)} + Then def task_id_2 = response.id + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And param page = 0 + When method get + Then match [200, 201, 204] contains responseStatus + Then match response[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id } ) + Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id_2 } ) + Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } \ No newline at end of file From 68ca9b8c6d5c6d975b94aec1218e1e530618960f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Thu, 5 Oct 2023 15:04:13 +0200 Subject: [PATCH 3/8] feat : 1st conformity scenario - v1 --- test/check-service-conformity.feature | 69 +++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature index ed0395b..d9a8f28 100644 --- a/test/check-service-conformity.feature +++ b/test/check-service-conformity.feature @@ -6,10 +6,11 @@ Background: * url 'http://localhost:8080/' Scenario: - * path 'healthcheck' - * method head + Given path 'healthcheck' + When method head -Scenario: Simple Conformity Scenario +Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check + # Create an account Given path 'api/accounts' And header Content-Type = 'application/json' And request { login: #(account_name) } @@ -17,6 +18,7 @@ Scenario: Simple Conformity Scenario Then match [200, 201, 204] contains responseStatus Then match response == { id: #uuid, login: #(account_name), creation_date: #notnull } Then def account_id = response.id + # Create list linked to the account Given path 'api/accounts',account_id,'lists' And header Content-Type = 'application/json' And def list_name = 'List-' + now() @@ -25,6 +27,7 @@ Scenario: Simple Conformity Scenario Then match [200, 201, 204] contains responseStatus Then match response == { id: #uuid, name: #(list_name), creation_date: #notnull , account_id: #(account_id)} Then def list_id = response.id + # Create 1 task on the list Given path 'api/lists',list_id,'tasks' And header Content-Type = 'application/json' And def task_name = 'Task-' + now() @@ -34,6 +37,7 @@ Scenario: Simple Conformity Scenario Then match [200, 201, 204] contains responseStatus Then match response == { id: #uuid, name: #(task_name), description: #(task_description) , creation_date: #notnull , list_id: #(list_id)} Then def task_id = response.id + # Check current list content Given path 'api/accounts',account_id,'lists' And header Content-Type = 'application/json' And param page = 0 @@ -41,12 +45,14 @@ Scenario: Simple Conformity Scenario Then match [200, 201, 204] contains responseStatus Then match response[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } Then match response[0].tasks[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + # Check stats Given path 'api/stats' And header Content-Type = 'application/json' When method get Then match [200, 201, 204] contains responseStatus Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) Then match sub_result[0] == { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } + # Create a 2nd task on the list Given path 'api/lists',list_id,'tasks' And header Content-Type = 'application/json' And def task_name_2 = 'Task-' + now() @@ -56,6 +62,7 @@ Scenario: Simple Conformity Scenario Then match [200, 201, 204] contains responseStatus Then match response == { id: #uuid, name: #(task_name_2), description: #(task_description_2) , creation_date: #notnull , list_id: #(list_id)} Then def task_id_2 = response.id + # Check current list content - should be 2 tasks Given path 'api/accounts',account_id,'lists' And header Content-Type = 'application/json' And param page = 0 @@ -65,4 +72,58 @@ Scenario: Simple Conformity Scenario Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id } ) Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id_2 } ) - Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } \ No newline at end of file + Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + # Create a 2nd list on the account + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And def list_name_2 = 'List-' + now() + And request { name: #(list_name_2) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, name: #(list_name_2), creation_date: #notnull , account_id: #(account_id)} + Then def list_id_2 = response.id + # Check current lists content - should be 2 tasks + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And param page = 0 + When method get + Then match [200, 201, 204] contains responseStatus + Then def lr1 = karate.filter(response, x => { return x.id == list_id } ) + Then match lr1[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id } ) + Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id_2 } ) + Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + Then def lr2 = karate.filter(response, x => { return x.id == list_id_2 } ) + Then match lr2[0] == { id: #(list_id_2), name: #(list_name_2), creation_date: #notnull , account_id: #(account_id) } + # Create 1 task on the 2nd list + Given path 'api/lists',list_id_2,'tasks' + And header Content-Type = 'application/json' + And request { name: #(task_name), description: #(task_description) } + When method post + Then match [200, 201, 204] contains responseStatus + Then match response == { id: #uuid, name: #(task_name), description: #(task_description) , creation_date: #notnull , list_id: #(list_id_2)} + Then def task_id_1_2 = response.id + # Check current lists content - should be 2 tasks + Given path 'api/accounts',account_id,'lists' + And header Content-Type = 'application/json' + And param page = 0 + When method get + Then match [200, 201, 204] contains responseStatus + Then def lr1 = karate.filter(response, x => { return x.id == list_id } ) + Then match lr1[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id } ) + Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id_2 } ) + Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + Then def lr2 = karate.filter(response, x => { return x.id == list_id_2 } ) + Then match lr2[0] == { id: #(list_id_2), name: #(list_name_2), creation_date: #notnull , account_id: #(account_id) , tasks: #notnull } + Then def r = karate.filter(lr2[0].tasks, x => { return x.id == task_id_1_2 } ) + Then match r[0] == { id: #(task_id_1_2), name: #(task_name), description: #(task_description), creation_date: #notnull } + # Check stats + Given path 'api/stats' + And header Content-Type = 'application/json' + When method get + Then match [200, 201, 204] contains responseStatus + Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) + Then match sub_result[0] == { account_id: #(account_id), account_login: #(account_name), list_count:2, task_avg:1.5 } \ No newline at end of file From 05574ac5ac3cea017017d6d8f030ff9975ffb6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Thu, 5 Oct 2023 15:42:54 +0200 Subject: [PATCH 4/8] fix: adding more tolerance --- test/check-service-conformity.feature | 45 ++++++++++++++------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature index d9a8f28..98b079e 100644 --- a/test/check-service-conformity.feature +++ b/test/check-service-conformity.feature @@ -16,7 +16,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { login: #(account_name) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, login: #(account_name), creation_date: #notnull } + Then match response contains { id: #uuid, login: #(account_name)} Then def account_id = response.id # Create list linked to the account Given path 'api/accounts',account_id,'lists' @@ -25,7 +25,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(list_name) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, name: #(list_name), creation_date: #notnull , account_id: #(account_id)} + Then match response contains { id: #uuid, name: #(list_name) } Then def list_id = response.id # Create 1 task on the list Given path 'api/lists',list_id,'tasks' @@ -35,7 +35,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(task_name), description: #(task_description) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, name: #(task_name), description: #(task_description) , creation_date: #notnull , list_id: #(list_id)} + Then match response contains { id: #uuid, name: #(task_name), description: #(task_description) , list_id: #(list_id) } Then def task_id = response.id # Check current list content Given path 'api/accounts',account_id,'lists' @@ -43,15 +43,16 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And param page = 0 When method get Then match [200, 201, 204] contains responseStatus - Then match response[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } - Then match response[0].tasks[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then print response + Then match response[0] contains { id: #(list_id), name: #(list_name), tasks: #notnull } + Then match response[0].tasks[0] contains { id: #(task_id), name: #(task_name), description: #(task_description) } # Check stats Given path 'api/stats' And header Content-Type = 'application/json' When method get Then match [200, 201, 204] contains responseStatus Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) - Then match sub_result[0] == { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } + Then match sub_result[0] contains { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } # Create a 2nd task on the list Given path 'api/lists',list_id,'tasks' And header Content-Type = 'application/json' @@ -60,7 +61,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(task_name_2), description: #(task_description_2) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, name: #(task_name_2), description: #(task_description_2) , creation_date: #notnull , list_id: #(list_id)} + Then match response contains { id: #uuid, name: #(task_name_2), description: #(task_description_2) , list_id: #(list_id) } Then def task_id_2 = response.id # Check current list content - should be 2 tasks Given path 'api/accounts',account_id,'lists' @@ -68,11 +69,11 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And param page = 0 When method get Then match [200, 201, 204] contains responseStatus - Then match response[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then match response[0] contains { id: #(list_id), name: #(list_name), tasks: #notnull } Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id } ) - Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then match r[0] contains { id: #(task_id), name: #(task_name), description: #(task_description) } Then def r = karate.filter(response[0].tasks, x => { return x.id == task_id_2 } ) - Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + Then match r[0] contains { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2) } # Create a 2nd list on the account Given path 'api/accounts',account_id,'lists' And header Content-Type = 'application/json' @@ -80,7 +81,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(list_name_2) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, name: #(list_name_2), creation_date: #notnull , account_id: #(account_id)} + Then match response contains { id: #uuid, name: #(list_name_2) } Then def list_id_2 = response.id # Check current lists content - should be 2 tasks Given path 'api/accounts',account_id,'lists' @@ -89,20 +90,20 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check When method get Then match [200, 201, 204] contains responseStatus Then def lr1 = karate.filter(response, x => { return x.id == list_id } ) - Then match lr1[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then match lr1[0] contains { id: #(list_id), name: #(list_name), tasks: #notnull } Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id } ) - Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then match r[0] contains { id: #(task_id), name: #(task_name), description: #(task_description) } Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id_2 } ) - Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + Then match r[0] contains { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2) } Then def lr2 = karate.filter(response, x => { return x.id == list_id_2 } ) - Then match lr2[0] == { id: #(list_id_2), name: #(list_name_2), creation_date: #notnull , account_id: #(account_id) } + Then match lr2[0] contains { id: #(list_id_2), name: #(list_name_2), account_id: #(account_id) } # Create 1 task on the 2nd list Given path 'api/lists',list_id_2,'tasks' And header Content-Type = 'application/json' And request { name: #(task_name), description: #(task_description) } When method post Then match [200, 201, 204] contains responseStatus - Then match response == { id: #uuid, name: #(task_name), description: #(task_description) , creation_date: #notnull , list_id: #(list_id_2)} + Then match response contains { id: #uuid, name: #(task_name), description: #(task_description), list_id: #(list_id_2)} Then def task_id_1_2 = response.id # Check current lists content - should be 2 tasks Given path 'api/accounts',account_id,'lists' @@ -111,19 +112,19 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check When method get Then match [200, 201, 204] contains responseStatus Then def lr1 = karate.filter(response, x => { return x.id == list_id } ) - Then match lr1[0] == { id: #(list_id), name: #(list_name), creation_date: #notnull , account_id: #(account_id), tasks: #notnull } + Then match lr1[0] contains { id: #(list_id), name: #(list_name), tasks: #notnull } Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id } ) - Then match r[0] == { id: #(task_id), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then match r[0] contains { id: #(task_id), name: #(task_name), description: #(task_description) } Then def r = karate.filter(lr1[0].tasks, x => { return x.id == task_id_2 } ) - Then match r[0] == { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2), creation_date: #notnull } + Then match r[0] contains { id: #(task_id_2), name: #(task_name_2), description: #(task_description_2)} Then def lr2 = karate.filter(response, x => { return x.id == list_id_2 } ) - Then match lr2[0] == { id: #(list_id_2), name: #(list_name_2), creation_date: #notnull , account_id: #(account_id) , tasks: #notnull } + Then match lr2[0] contains { id: #(list_id_2), name: #(list_name_2), tasks: #notnull } Then def r = karate.filter(lr2[0].tasks, x => { return x.id == task_id_1_2 } ) - Then match r[0] == { id: #(task_id_1_2), name: #(task_name), description: #(task_description), creation_date: #notnull } + Then match r[0] contains { id: #(task_id_1_2), name: #(task_name), description: #(task_description)} # Check stats Given path 'api/stats' And header Content-Type = 'application/json' When method get Then match [200, 201, 204] contains responseStatus Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) - Then match sub_result[0] == { account_id: #(account_id), account_login: #(account_name), list_count:2, task_avg:1.5 } \ No newline at end of file + Then match sub_result[0] contains { account_id: #(account_id), account_login: #(account_name), list_count:2, task_avg:1.5 } \ No newline at end of file From d8521f35cc4fa24f8c9a67a1b07555b7a6e4351b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Thu, 5 Oct 2023 16:48:03 +0200 Subject: [PATCH 5/8] fix: healthcheck signature --- service/EcobenchmarkBackEnd-0.0.1-swagger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml b/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml index d45e064..4d37536 100644 --- a/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml +++ b/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml @@ -125,7 +125,7 @@ paths: items: $ref: '#/components/schemas/AccountStatistic' /healthcheck: - get: + head: tags: - developers summary: returns the health of the service From 9ff38a185bd5f850df4dc6140f71cbdead3a8295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Thu, 5 Oct 2023 16:58:11 +0200 Subject: [PATCH 6/8] fix: swagger + more tolerance --- service/EcobenchmarkBackEnd-0.0.1-swagger.yaml | 16 ++++++++-------- test/check-service-conformity.feature | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml b/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml index 4d37536..47c1a20 100644 --- a/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml +++ b/service/EcobenchmarkBackEnd-0.0.1-swagger.yaml @@ -181,13 +181,13 @@ components: type: string format: uuid example: 276f6a6f-0afa-4e50-9e39-7130f5aea9d2 - accountId: + account_id: type: string example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: My Task List - creationDate: + creation_date: type: string format: date-time example: '2022-06-29T13:37:00.001Z' @@ -213,7 +213,7 @@ components: type: string format: uuid example: c6516320-e069-4238-a5c3-a57df2c1bc32 - listId: + list_id: type: string example: 276f6a6f-0afa-4e50-9e39-7130f5aea9d2 name: @@ -222,23 +222,23 @@ components: description: type: string example: Just do it ! - creationDate: + creation_date: type: string format: date-time example: '2022-06-29T13:37:00.001Z' AccountStatistic: type: object properties: - accountId: + account_id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 - accountLogin: + account_login: type: string example: My Personal Account - listCount: + list_count: type: number example: 42 - taskAvg: + task_avg: type: number example: 1337 \ No newline at end of file diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature index 98b079e..ea9b11b 100644 --- a/test/check-service-conformity.feature +++ b/test/check-service-conformity.feature @@ -35,7 +35,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(task_name), description: #(task_description) } When method post Then match [200, 201, 204] contains responseStatus - Then match response contains { id: #uuid, name: #(task_name), description: #(task_description) , list_id: #(list_id) } + Then match response contains { id: #uuid, name: #(task_name), description: #(task_description)} Then def task_id = response.id # Check current list content Given path 'api/accounts',account_id,'lists' @@ -50,6 +50,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check Given path 'api/stats' And header Content-Type = 'application/json' When method get + Then print response Then match [200, 201, 204] contains responseStatus Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) Then match sub_result[0] contains { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } @@ -61,7 +62,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(task_name_2), description: #(task_description_2) } When method post Then match [200, 201, 204] contains responseStatus - Then match response contains { id: #uuid, name: #(task_name_2), description: #(task_description_2) , list_id: #(list_id) } + Then match response contains { id: #uuid, name: #(task_name_2), description: #(task_description_2) } Then def task_id_2 = response.id # Check current list content - should be 2 tasks Given path 'api/accounts',account_id,'lists' @@ -103,7 +104,7 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And request { name: #(task_name), description: #(task_description) } When method post Then match [200, 201, 204] contains responseStatus - Then match response contains { id: #uuid, name: #(task_name), description: #(task_description), list_id: #(list_id_2)} + Then match response contains { id: #uuid, name: #(task_name), description: #(task_description)} Then def task_id_1_2 = response.id # Check current lists content - should be 2 tasks Given path 'api/accounts',account_id,'lists' From 1567776139221fac6aadeaec74a3fb4a15fc056e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Fri, 6 Oct 2023 09:15:36 +0200 Subject: [PATCH 7/8] feat: documentation and last adjustment --- CONTRIBUTING.md | 9 +++++++++ test/README.md | 2 ++ test/check-service-conformity.feature | 4 +--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7c6748..a2c837f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,6 +36,15 @@ Each service must respect : Reference implementation is the [golang implementation](./service/go-pgx). +### Acceptance criteria + +Service should pass the [conformity tests](./test/check-service-conformity.feature) - For help to execute test go here : https://github.com/karatelabs/karate + +Service's docker should have 2 environment variables : + +- `DATABASE_URL` : Example of value injected: postgres://postgres:mysecretpassword@database:5432/postgres - url signature can be change for each service +- `DATABASE_POOL_MAX` : setup to 20 by default + #### API Contract API Contract must respect the following [API Definition documentation](./service/specs.md). diff --git a/test/README.md b/test/README.md index a1d4cdd..315a352 100644 --- a/test/README.md +++ b/test/README.md @@ -2,3 +2,5 @@ ### Test Script to check the good behavior of each service implementation. +Get help here on how to launch the test : https://github.com/karatelabs/karate + diff --git a/test/check-service-conformity.feature b/test/check-service-conformity.feature index ea9b11b..8c250ef 100644 --- a/test/check-service-conformity.feature +++ b/test/check-service-conformity.feature @@ -5,7 +5,7 @@ Background: * def account_name = 'Conformity-' + now() * url 'http://localhost:8080/' -Scenario: +Scenario: Healthcheck Given path 'healthcheck' When method head @@ -43,14 +43,12 @@ Scenario: Simple Conformity Scenario - API Behavior and Cache agressive check And param page = 0 When method get Then match [200, 201, 204] contains responseStatus - Then print response Then match response[0] contains { id: #(list_id), name: #(list_name), tasks: #notnull } Then match response[0].tasks[0] contains { id: #(task_id), name: #(task_name), description: #(task_description) } # Check stats Given path 'api/stats' And header Content-Type = 'application/json' When method get - Then print response Then match [200, 201, 204] contains responseStatus Then def sub_result = karate.filter(response, x => { return x.account_id == account_id } ) Then match sub_result[0] contains { account_id: #(account_id), account_login: #(account_name), list_count:1, task_avg:1 } From fabbb345b1f3196eff32cd0e3531724781053153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Youen=20Ch=C3=A9n=C3=A9?= Date: Mon, 9 Oct 2023 18:52:38 +0200 Subject: [PATCH 8/8] doc: link on different flavor to launch tests. --- test/README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/README.md b/test/README.md index 315a352..eb585f0 100644 --- a/test/README.md +++ b/test/README.md @@ -2,5 +2,16 @@ ### Test Script to check the good behavior of each service implementation. -Get help here on how to launch the test : https://github.com/karatelabs/karate +Get help here on how to launch the test : https://github.com/karatelabs/karate/wiki/Get-Started +You have different flavour to launch test. + +You can use a plugin on your favorite IDE in order to launch test locally for dev purpose : + +- https://github.com/karatelabs/karate/wiki/Get-Started:-Visual-Studio-Code +- https://github.com/karatelabs/karate/wiki/Get-Started:-JetBrains-IntelliJ + +Or use command line style for CI integration : + +- https://github.com/karatelabs/karate/wiki/Get-Started:-Maven-and-Gradle +- https://github.com/karatelabs/karate/wiki/Get-Started:-Other-Runtime-Options \ No newline at end of file