2021-11-16 13:04:22 +00:00
package query
import (
2023-02-27 21:36:43 +00:00
"context"
2021-11-16 13:04:22 +00:00
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"regexp"
"testing"
2022-10-06 12:23:59 +00:00
"time"
2021-11-16 13:04:22 +00:00
2022-06-01 06:11:48 +00:00
sq "github.com/Masterminds/squirrel"
2022-04-26 23:01:45 +00:00
"github.com/zitadel/zitadel/internal/domain"
2021-11-16 13:04:22 +00:00
)
2023-02-27 21:36:43 +00:00
var (
prepareFlowStmt = ` SELECT projections.actions3.id, ` +
` projections.actions3.creation_date, ` +
` projections.actions3.change_date, ` +
` projections.actions3.resource_owner, ` +
` projections.actions3.action_state, ` +
` projections.actions3.sequence, ` +
` projections.actions3.name, ` +
` projections.actions3.script, ` +
` projections.actions3.allowed_to_fail, ` +
` projections.actions3.timeout, ` +
2023-11-20 15:21:08 +00:00
` projections.flow_triggers3.trigger_type, ` +
` projections.flow_triggers3.trigger_sequence, ` +
` projections.flow_triggers3.flow_type, ` +
` projections.flow_triggers3.change_date, ` +
` projections.flow_triggers3.sequence, ` +
` projections.flow_triggers3.resource_owner ` +
` FROM projections.flow_triggers3 ` +
` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id `
// ` AS OF SYSTEM TIME '-1 ms'`
2023-02-27 21:36:43 +00:00
prepareFlowCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"state" ,
"sequence" ,
"name" ,
"script" ,
"allowed_to_fail" ,
"timeout" ,
// flow
"trigger_type" ,
"trigger_sequence" ,
"flow_type" ,
"change_date" ,
"sequence" ,
"resource_owner" ,
}
prepareTriggerActionStmt = ` SELECT projections.actions3.id, ` +
` projections.actions3.creation_date, ` +
` projections.actions3.change_date, ` +
` projections.actions3.resource_owner, ` +
` projections.actions3.action_state, ` +
` projections.actions3.sequence, ` +
` projections.actions3.name, ` +
` projections.actions3.script, ` +
` projections.actions3.allowed_to_fail, ` +
` projections.actions3.timeout ` +
2023-11-20 15:21:08 +00:00
` FROM projections.flow_triggers3 ` +
` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id `
// ` AS OF SYSTEM TIME '-1 ms'`
2023-02-27 21:36:43 +00:00
prepareTriggerActionCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"state" ,
"sequence" ,
"name" ,
"script" ,
"allowed_to_fail" ,
"timeout" ,
}
2023-11-20 15:21:08 +00:00
prepareFlowTypeStmt = ` SELECT projections.flow_triggers3.flow_type ` +
` FROM projections.flow_triggers3 `
// ` AS OF SYSTEM TIME '-1 ms'`
2023-02-27 21:36:43 +00:00
prepareFlowTypeCols = [ ] string {
"flow_type" ,
}
)
2021-11-16 13:04:22 +00:00
func Test_FlowPrepares ( t * testing . T ) {
type want struct {
sqlExpectations sqlExpectation
err checkErr
}
tests := [ ] struct {
name string
prepare interface { }
want want
object interface { }
} {
{
2022-06-01 06:11:48 +00:00
name : "prepareFlowQuery no result" ,
2023-02-27 21:36:43 +00:00
prepare : func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Flow , error ) ) {
return prepareFlowQuery ( ctx , db , domain . FlowTypeExternalAuthentication )
2022-06-01 06:11:48 +00:00
} ,
2021-11-16 13:04:22 +00:00
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowStmt ) ,
2021-11-16 13:04:22 +00:00
nil ,
nil ,
) ,
} ,
2022-06-01 06:11:48 +00:00
object : & Flow {
TriggerActions : map [ domain . TriggerType ] [ ] * Action { } ,
Type : domain . FlowTypeExternalAuthentication ,
} ,
2021-11-16 13:04:22 +00:00
} ,
{
2022-06-01 06:11:48 +00:00
name : "prepareFlowQuery one action" ,
2023-02-27 21:36:43 +00:00
prepare : func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Flow , error ) ) {
return prepareFlowQuery ( ctx , db , domain . FlowTypeExternalAuthentication )
2022-06-01 06:11:48 +00:00
} ,
2021-11-16 13:04:22 +00:00
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowStmt ) ,
prepareFlowCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
"action-id" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name" ,
"script" ,
2022-10-06 12:23:59 +00:00
true ,
10000000000 ,
2021-11-16 13:04:22 +00:00
domain . TriggerTypePreCreation ,
uint64 ( 20211109 ) ,
domain . FlowTypeExternalAuthentication ,
2022-03-23 08:02:39 +00:00
testNow ,
uint64 ( 20211115 ) ,
"owner" ,
2021-11-16 13:04:22 +00:00
} ,
} ,
) ,
} ,
object : & Flow {
2022-03-23 08:02:39 +00:00
ChangeDate : testNow ,
ResourceOwner : "owner" ,
Sequence : 20211115 ,
Type : domain . FlowTypeExternalAuthentication ,
2021-11-16 13:04:22 +00:00
TriggerActions : map [ domain . TriggerType ] [ ] * Action {
domain . TriggerTypePreCreation : {
{
ID : "action-id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : true ,
timeout : 10 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
} ,
} ,
} ,
} ,
{
2022-06-01 06:11:48 +00:00
name : "prepareFlowQuery multiple actions" ,
2023-02-27 21:36:43 +00:00
prepare : func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Flow , error ) ) {
return prepareFlowQuery ( ctx , db , domain . FlowTypeExternalAuthentication )
2022-06-01 06:11:48 +00:00
} ,
2021-11-16 13:04:22 +00:00
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowStmt ) ,
prepareFlowCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
"action-id-pre" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name-pre" ,
"script" ,
2022-10-06 12:23:59 +00:00
true ,
10000000000 ,
2021-11-16 13:04:22 +00:00
domain . TriggerTypePreCreation ,
uint64 ( 20211109 ) ,
domain . FlowTypeExternalAuthentication ,
2022-03-23 08:02:39 +00:00
testNow ,
uint64 ( 20211115 ) ,
"owner" ,
2021-11-16 13:04:22 +00:00
} ,
{
"action-id-post" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name-post" ,
"script" ,
2022-10-06 12:23:59 +00:00
false ,
5000000000 ,
2021-11-16 13:04:22 +00:00
domain . TriggerTypePostCreation ,
uint64 ( 20211109 ) ,
domain . FlowTypeExternalAuthentication ,
2022-03-23 08:02:39 +00:00
testNow ,
uint64 ( 20211115 ) ,
"owner" ,
2021-11-16 13:04:22 +00:00
} ,
} ,
) ,
} ,
object : & Flow {
2022-03-23 08:02:39 +00:00
ChangeDate : testNow ,
ResourceOwner : "owner" ,
Sequence : 20211115 ,
Type : domain . FlowTypeExternalAuthentication ,
2021-11-16 13:04:22 +00:00
TriggerActions : map [ domain . TriggerType ] [ ] * Action {
domain . TriggerTypePreCreation : {
{
ID : "action-id-pre" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name-pre" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : true ,
timeout : 10 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
} ,
domain . TriggerTypePostCreation : {
{
ID : "action-id-post" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name-post" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : false ,
timeout : 5 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
} ,
} ,
} ,
} ,
{
2022-06-01 06:11:48 +00:00
name : "prepareFlowQuery no action" ,
2023-02-27 21:36:43 +00:00
prepare : func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Flow , error ) ) {
return prepareFlowQuery ( ctx , db , domain . FlowTypeExternalAuthentication )
2022-06-01 06:11:48 +00:00
} ,
2021-11-16 13:04:22 +00:00
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowStmt ) ,
prepareFlowCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
2022-02-02 08:04:05 +00:00
nil ,
2022-10-06 12:23:59 +00:00
nil ,
nil ,
2021-11-16 13:04:22 +00:00
domain . TriggerTypePostCreation ,
uint64 ( 20211109 ) ,
domain . FlowTypeExternalAuthentication ,
2022-03-23 08:02:39 +00:00
testNow ,
uint64 ( 20211115 ) ,
"owner" ,
2021-11-16 13:04:22 +00:00
} ,
} ,
) ,
} ,
object : & Flow {
2022-03-23 08:02:39 +00:00
ChangeDate : testNow ,
ResourceOwner : "owner" ,
Sequence : 20211115 ,
2021-11-16 13:04:22 +00:00
Type : domain . FlowTypeExternalAuthentication ,
TriggerActions : map [ domain . TriggerType ] [ ] * Action { } ,
} ,
} ,
{
2022-06-01 06:11:48 +00:00
name : "prepareFlowQuery sql err" ,
2023-02-27 21:36:43 +00:00
prepare : func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Flow , error ) ) {
return prepareFlowQuery ( ctx , db , domain . FlowTypeExternalAuthentication )
2022-06-01 06:11:48 +00:00
} ,
2021-11-16 13:04:22 +00:00
want : want {
sqlExpectations : mockQueryErr (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowStmt ) ,
2021-11-16 13:04:22 +00:00
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : nil ,
} ,
{
name : "prepareTriggerActionsQuery no result" ,
prepare : prepareTriggerActionsQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareTriggerActionStmt ) ,
2021-11-16 13:04:22 +00:00
nil ,
nil ,
) ,
} ,
object : [ ] * Action { } ,
} ,
{
name : "prepareTriggerActionsQuery one result" ,
prepare : prepareTriggerActionsQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareTriggerActionStmt ) ,
prepareTriggerActionCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
"action-id" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . AddressStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name" ,
"script" ,
2022-10-06 12:23:59 +00:00
true ,
10000000000 ,
2021-11-16 13:04:22 +00:00
} ,
} ,
) ,
} ,
object : [ ] * Action {
{
ID : "action-id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : true ,
timeout : 10 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
} ,
} ,
{
name : "prepareTriggerActionsQuery multiple results" ,
prepare : prepareTriggerActionsQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareTriggerActionStmt ) ,
prepareTriggerActionCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
"action-id-1" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . AddressStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name-1" ,
"script" ,
2022-10-06 12:23:59 +00:00
true ,
10000000000 ,
2021-11-16 13:04:22 +00:00
} ,
{
"action-id-2" ,
testNow ,
testNow ,
"ro" ,
2022-02-02 08:04:05 +00:00
domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
uint64 ( 20211115 ) ,
"action-name-2" ,
"script" ,
2022-10-06 12:23:59 +00:00
false ,
5000000000 ,
2021-11-16 13:04:22 +00:00
} ,
} ,
) ,
} ,
object : [ ] * Action {
{
ID : "action-id-1" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name-1" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : true ,
timeout : 10 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
{
ID : "action-id-2" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "ro" ,
2022-02-02 08:04:05 +00:00
State : domain . ActionStateActive ,
2021-11-16 13:04:22 +00:00
Sequence : 20211115 ,
Name : "action-name-2" ,
Script : "script" ,
2022-10-06 12:23:59 +00:00
AllowedToFail : false ,
timeout : 5 * time . Second ,
2021-11-16 13:04:22 +00:00
} ,
} ,
} ,
{
name : "prepareTriggerActionsQuery sql err" ,
prepare : prepareTriggerActionsQuery ,
want : want {
sqlExpectations : mockQueryErr (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareTriggerActionStmt ) ,
2021-11-16 13:04:22 +00:00
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : nil ,
} ,
{
name : "prepareFlowTypesQuery no result" ,
prepare : prepareFlowTypesQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowTypeStmt ) ,
2021-11-16 13:04:22 +00:00
nil ,
nil ,
) ,
} ,
object : [ ] domain . FlowType { } ,
} ,
{
name : "prepareFlowTypesQuery one result" ,
prepare : prepareFlowTypesQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowTypeStmt ) ,
prepareFlowTypeCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
domain . FlowTypeExternalAuthentication ,
} ,
} ,
) ,
} ,
object : [ ] domain . FlowType {
domain . FlowTypeExternalAuthentication ,
} ,
} ,
{
name : "prepareFlowTypesQuery multiple results" ,
prepare : prepareFlowTypesQuery ,
want : want {
sqlExpectations : mockQueries (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowTypeStmt ) ,
prepareFlowTypeCols ,
2021-11-16 13:04:22 +00:00
[ ] [ ] driver . Value {
{
domain . FlowTypeExternalAuthentication ,
} ,
{
domain . FlowTypeUnspecified ,
} ,
} ,
) ,
} ,
object : [ ] domain . FlowType {
domain . FlowTypeExternalAuthentication ,
domain . FlowTypeUnspecified ,
} ,
} ,
{
name : "prepareFlowTypesQuery sql err" ,
prepare : prepareFlowTypesQuery ,
want : want {
sqlExpectations : mockQueryErr (
2023-02-27 21:36:43 +00:00
regexp . QuoteMeta ( prepareFlowTypeStmt ) ,
2021-11-16 13:04:22 +00:00
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : nil ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-02-27 21:36:43 +00:00
assertPrepare ( t , tt . prepare , tt . object , tt . want . sqlExpectations , tt . want . err , defaultPrepareArgs ... )
2021-11-16 13:04:22 +00:00
} )
}
}