diff --git a/asserter/asserter.go b/asserter/asserter.go index da68bfe6..3cd9029e 100644 --- a/asserter/asserter.go +++ b/asserter/asserter.go @@ -16,10 +16,17 @@ package asserter import ( "context" + "errors" "github.com/coinbase/rosetta-sdk-go/types" ) +var ( + // ErrAsserterNotInitialized is returned when some call in the asserter + // package requires the asserter to be initialized first. + ErrAsserterNotInitialized = errors.New("asserter not initialized") +) + // Asserter contains all logic to perform static // validation on Rosetta Server responses. type Asserter struct { @@ -81,12 +88,3 @@ func NewWithOptions( return asserter } - -func (a *Asserter) operationStatuses() []string { - statuses := []string{} - for k := range a.operationStatusMap { - statuses = append(statuses, k) - } - - return statuses -} diff --git a/asserter/asserter_test.go b/asserter/asserter_test.go index fdf91e97..3f9d861b 100644 --- a/asserter/asserter_test.go +++ b/asserter/asserter_test.go @@ -1,3 +1,17 @@ +// Copyright 2020 Coinbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package asserter import ( diff --git a/asserter/block.go b/asserter/block.go index cdd2eb03..a7a8aa60 100644 --- a/asserter/block.go +++ b/asserter/block.go @@ -106,7 +106,7 @@ func AccountIdentifier(account *types.AccountIdentifier) error { // AFTER an operation has been validated. func (a *Asserter) OperationSuccessful(operation *types.Operation) (bool, error) { if a == nil { - return false, errors.New("must initialize asserter") + return false, ErrAsserterNotInitialized } val, ok := a.operationStatusMap[operation.Status] @@ -117,6 +117,21 @@ func (a *Asserter) OperationSuccessful(operation *types.Operation) (bool, error) return val, nil } +// operationStatuses returns all operation statuses the +// asserter consider valid. +func (a *Asserter) operationStatuses() ([]string, error) { + if a == nil { + return nil, ErrAsserterNotInitialized + } + + statuses := []string{} + for k := range a.operationStatusMap { + statuses = append(statuses, k) + } + + return statuses, nil +} + // Operation ensures a types.Operation has a valid // type, status, and amount. func (a *Asserter) Operation( @@ -124,7 +139,7 @@ func (a *Asserter) Operation( index int64, ) error { if a == nil { - return errors.New("must initialize asserter") + return ErrAsserterNotInitialized } if operation == nil { @@ -139,7 +154,12 @@ func (a *Asserter) Operation( return fmt.Errorf("Operation.Type %s is invalid", operation.Type) } - if operation.Status == "" || !contains(a.operationStatuses(), operation.Status) { + validOperationStatuses, err := a.operationStatuses() + if err != nil { + return err + } + + if operation.Status == "" || !contains(validOperationStatuses, operation.Status) { return fmt.Errorf("Operation.Status %s is invalid", operation.Status) } @@ -213,7 +233,7 @@ func (a *Asserter) Transaction( transaction *types.Transaction, ) error { if a == nil { - return errors.New("must initialize asserter") + return ErrAsserterNotInitialized } if transaction == nil { @@ -248,7 +268,7 @@ func (a *Asserter) Block( block *types.Block, ) error { if a == nil { - return errors.New("must initialize asserter") + return ErrAsserterNotInitialized } if block == nil {