func Test_Validator_ThrowsErrorFromSetupsAndTeardowns(t *testing.T) {
	testErr := errors.New("action error")
	fn := func() error {
		return testErr
	}

	sa := &stateAction{setup: nil, teardown: nil}

	interaction, _ := consumer.NewInteraction("description", "state", provider.NewJSONRequest("Get", "/", "", nil), provider.NewJSONResponse(200, nil))
	f := io.NewPactFile("consumer", "provider", []*consumer.Interaction{interaction})

	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(interaction.Response.Status)
	}))
	defer s.Close()

	u, _ := url.Parse(s.URL)

	//test setup action for every interaction
	v := newConsumerValidator(fn, nil, DefaultLogger)
	v.ProviderService(&http.Client{}, u)
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected %s", testErr)
	} else if err != testErr {
		t.Errorf("expected %s, got %s", testErr, err)
	}

	//test teardown action for every interaction
	v = newConsumerValidator(nil, fn, DefaultLogger)
	v.ProviderService(&http.Client{}, u)
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected %s", testErr)
	} else if err != testErr {
		t.Errorf("expected %s, got %s", testErr, err)
	}

	//test setup action for specific interaction
	sa = &stateAction{setup: fn, teardown: nil}
	v = newConsumerValidator(nil, fn, DefaultLogger)
	v.ProviderService(&http.Client{}, u)
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected %s", testErr)
	} else if err != testErr {
		t.Errorf("expected %s, got %s", testErr, err)
	}

	//test teardown action for every interaction
	sa = &stateAction{setup: nil, teardown: fn}
	v = newConsumerValidator(nil, fn, DefaultLogger)
	v.ProviderService(&http.Client{}, u)
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected %s", testErr)
	} else if err != testErr {
		t.Errorf("expected %s, got %s", testErr, err)
	}
}
func Test_Validator_ReturnsErrorWhenRequestCreationFails(t *testing.T) {
	v := newConsumerValidator(nil, nil, DefaultLogger)
	interaction, _ := consumer.NewInteraction("description", "state", provider.NewJSONRequest("Get", "/", "", nil), provider.NewJSONResponse(200, nil))
	f := io.NewPactFile("consumer", "provider", []*consumer.Interaction{interaction})
	sa := &stateAction{setup: nil, teardown: nil}

	v.ProviderService(&http.Client{}, &url.URL{})
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected error whilst creating the request")
	}
}
func (p *mockProviderService) registerInteraction() error {
	interaction, err := consumer.NewInteraction(p.description, p.state, p.providerRequest, p.providerResponse)
	if err != nil {
		return err
	}
	if err := p.service.RegisterInteraction(interaction); err != nil {
		return err
	}

	p.resetTransientState()
	return nil
}
func getFakeInteraction() *consumer.Interaction {
	header := make(http.Header)
	header.Add("content-type", "application/json")
	i, _ := consumer.NewInteraction("description of the interaction",
		"some state",
		provider.NewJSONRequest("POST", "/", "param=xyzmk", header),
		provider.NewJSONResponse(201, header))

	i.Request.SetBody(`{ "firstName": "John", "lastName": "Doe" }`)
	i.Response.SetBody(`{"result": true}`)
	return i
}
func Test_Validator_ExecutesSetupsAndTeardowns(t *testing.T) {
	i := 1
	v := newConsumerValidator(func() error {
		if i != 1 {
			t.Errorf("Expected this action to be called at %v position but is at %d", 1, i)
		} else {
			i++
		}
		return nil
	}, func() error {
		if i != 4 {
			t.Errorf("Expected this action to be called at %d position but is at %d", 4, i)
		}
		return nil
	}, DefaultLogger)

	sa := &stateAction{setup: func() error {
		if i != 2 {
			t.Errorf("Expected this action to be called at %d position but is at %d", 2, i)
		} else {
			i++
		}
		return nil
	}, teardown: func() error {
		if i != 3 {
			t.Errorf("Expected this action to be called at %d position but is at %d", 3, i)
		} else {
			i++
		}
		return nil
	}}

	interaction, _ := consumer.NewInteraction("description", "state", provider.NewJSONRequest("Get", "/", "", nil), provider.NewJSONResponse(200, nil))
	f := io.NewPactFile("consumer", "provider", []*consumer.Interaction{interaction})

	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(interaction.Response.Status)
	}))
	defer s.Close()
	u, _ := url.Parse(s.URL)

	v.ProviderService(&http.Client{}, u)
	if res, err := v.Validate(f, map[string]*stateAction{"state": sa}); err != nil {
		t.Error(err)
	} else if !res {
		t.Error("Validation Failed")
	} else if i != 4 {
		t.Error("Setup and teardown actions were not called correctly")
	}
}
func Test_Validator_ReturnsErrorWhenProvierStateIsMissing(t *testing.T) {
	v := newConsumerValidator(nil, nil, DefaultLogger)
	interaction, _ := consumer.NewInteraction("description", "state", provider.NewJSONRequest("Get", "/", "", nil), provider.NewJSONResponse(200, nil))
	f := io.NewPactFile("consumer", "provider", []*consumer.Interaction{interaction})

	expErrMsg := fmt.Sprintf(errNotFoundProviderStateMsg, interaction.State)
	v.ProviderService(&http.Client{}, &url.URL{})
	if _, err := v.Validate(f, nil); err == nil {
		t.Errorf("expected %s", expErrMsg)
	} else if err.Error() != expErrMsg {
		t.Errorf("expected %s, got %s", expErrMsg, err)
	}

}
func Test_Validator_ReturnsErrorFromResponseMatcher(t *testing.T) {
	v := newConsumerValidator(nil, nil, DefaultLogger)
	r := provider.NewJSONResponse(200, nil)
	r.SetBody(`{"name":"John Doe"}`)
	interaction, _ := consumer.NewInteraction("description", "state", provider.NewJSONRequest("Get", "/", "", nil), r)
	f := io.NewPactFile("consumer", "provider", []*consumer.Interaction{interaction})
	sa := &stateAction{setup: nil, teardown: nil}
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(interaction.Response.Status)
		w.Write([]byte("bad json"))
	}))
	defer s.Close()
	u, _ := url.Parse(s.URL)

	v.ProviderService(&http.Client{}, u)
	if _, err := v.Validate(f, map[string]*stateAction{"state": sa}); err == nil {
		t.Errorf("expected error from response matcher")
	}
}