Ejemplo n.º 1
0
func TestMatchers(t *testing.T) {
	type e interface{}
	type testCase struct {
		matcher gomock.Matcher
		yes, no []e
	}
	tests := []testCase{
		testCase{gomock.Any(), []e{3, nil, "foo"}, nil},
		testCase{gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}},
		testCase{gomock.Nil(),
			[]e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)},
			[]e{"", 0, make(chan bool), errors.New("err"), new(int)}},
		testCase{gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}},
	}
	for i, test := range tests {
		for _, x := range test.yes {
			if !test.matcher.Matches(x) {
				t.Errorf(`test %d: "%v %s" should be true.`, i, x, test.matcher)
			}
		}
		for _, x := range test.no {
			if test.matcher.Matches(x) {
				t.Errorf(`test %d: "%v %s" should be false.`, i, x, test.matcher)
			}
		}
	}
}
Ejemplo n.º 2
0
func TestConnector_PostSubscriptionNoMocks(t *testing.T) {
	_, finish := testutil.NewMockCtrl(t)
	defer finish()

	a := assert.New(t)

	recorder := httptest.NewRecorder()
	conn, mocks := getTestConnector(t, Config{
		Name:       "test",
		Schema:     "test",
		Prefix:     "/connector/",
		URLPattern: "/{device_token}/{user_id}/{topic:.*}",
	}, false, false)

	entriesC := make(chan [2]string)
	mocks.kvstore.EXPECT().Iterate(gomock.Eq("test"), gomock.Eq("")).Return(entriesC)
	close(entriesC)

	mocks.kvstore.EXPECT().Put(gomock.Eq("test"), gomock.Eq(GenerateKey("/topic1", map[string]string{
		"device_token": "device1",
		"user_id":      "user1",
	})), gomock.Any())

	mocks.router.EXPECT().Subscribe(gomock.Any())

	err := conn.Start()
	a.NoError(err)
	defer conn.Stop()

	req, err := http.NewRequest(http.MethodPost, "/connector/device1/user1/topic1", strings.NewReader(""))
	a.NoError(err)
	conn.ServeHTTP(recorder, req)
	a.Equal(`{"subscribed":"/topic1"}`, recorder.Body.String())
	time.Sleep(100 * time.Millisecond)
}
Ejemplo n.º 3
0
func TestRemember(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockIndex := mock_user.NewMockIndex(ctrl)
	mockIndex.EXPECT().Put("a", 1)            // literals work
	mockIndex.EXPECT().Put("b", gomock.Eq(2)) // matchers work too

	// NillableRet returns error. Not declaring it should result in a nil return.
	mockIndex.EXPECT().NillableRet()
	// Calls that returns something assignable to the return type.
	boolc := make(chan bool)
	// In this case, "chan bool" is assignable to "chan<- bool".
	mockIndex.EXPECT().ConcreteRet().Return(boolc)
	// In this case, nil is assignable to "chan<- bool".
	mockIndex.EXPECT().ConcreteRet().Return(nil)

	// Should be able to place expectations on variadic methods.
	mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) // direct args
	tri := []interface{}{1, 3, 6, 10, 15}
	mockIndex.EXPECT().Ellip("%d", tri...) // args from slice
	mockIndex.EXPECT().EllipOnly(gomock.Eq("arg"))

	user.Remember(mockIndex, []string{"a", "b"}, []interface{}{1, 2})
	// Check the ConcreteRet calls.
	if c := mockIndex.ConcreteRet(); c != boolc {
		t.Errorf("ConcreteRet: got %v, want %v", c, boolc)
	}
	if c := mockIndex.ConcreteRet(); c != nil {
		t.Errorf("ConcreteRet: got %v, want nil", c)
	}

	// Try one with an action.
	calledString := ""
	mockIndex.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(key string, _ interface{}) {
		calledString = key
	})
	mockIndex.EXPECT().NillableRet()
	user.Remember(mockIndex, []string{"blah"}, []interface{}{7})
	if calledString != "blah" {
		t.Fatalf(`Uh oh. %q != "blah"`, calledString)
	}

	// Use Do with a nil arg.
	mockIndex.EXPECT().Put("nil-key", gomock.Any()).Do(func(key string, value interface{}) {
		if value != nil {
			t.Errorf("Put did not pass through nil; got %v", value)
		}
	})
	mockIndex.EXPECT().NillableRet()
	user.Remember(mockIndex, []string{"nil-key"}, []interface{}{nil})
}
Ejemplo n.º 4
0
func TestConnector_GetListWithFilters(t *testing.T) {
	_, finish := testutil.NewMockCtrl(t)
	defer finish()

	a := assert.New(t)

	recorder := httptest.NewRecorder()
	conn, mocks := getTestConnector(t, Config{
		Name:       "test",
		Schema:     "test",
		Prefix:     "/connector/",
		URLPattern: "/{device_token}/{user_id}/{topic:.*}",
	}, true, false)

	mocks.manager.EXPECT().Filter(gomock.Eq(map[string]string{
		"filter1": "value1",
		"filter2": "value2",
	})).Return([]Subscriber{})

	req, err := http.NewRequest(
		http.MethodGet,
		"/connector/?filter1=value1&filter2=value2",
		strings.NewReader(""))
	a.NoError(err)

	conn.ServeHTTP(recorder, req)
}
Ejemplo n.º 5
0
func TestConnector_DeleteSubscription(t *testing.T) {
	_, finish := testutil.NewMockCtrl(t)
	defer finish()

	a := assert.New(t)

	recorder := httptest.NewRecorder()
	conn, mocks := getTestConnector(t, Config{
		Name:       "test",
		Schema:     "test",
		Prefix:     "/connector/",
		URLPattern: "/{device_token}/{user_id}/{topic:.*}",
	}, true, false)

	subscriber := NewMockSubscriber(testutil.MockCtrl)
	mocks.manager.EXPECT().Find(gomock.Eq(GenerateKey("/topic1", map[string]string{
		"device_token": "device1",
		"user_id":      "user1",
	}))).Return(subscriber)
	mocks.manager.EXPECT().Remove(subscriber).Return(nil)

	req, err := http.NewRequest(http.MethodDelete, "/connector/device1/user1/topic1", strings.NewReader(""))
	a.NoError(err)
	conn.ServeHTTP(recorder, req)
	a.Equal(`{"unsubscribed":"/topic1"}`, recorder.Body.String())
	time.Sleep(200 * time.Millisecond)
}
Ejemplo n.º 6
0
func TestConnector_StartWithSubscriptions(t *testing.T) {
	_, finish := testutil.NewMockCtrl(t)
	defer finish()

	a := assert.New(t)
	conn, mocks := getTestConnector(t, Config{
		Name:       "test",
		Schema:     "test",
		Prefix:     "/connector/",
		URLPattern: "/{device_token}/{user_id}/{topic:.*}",
	}, false, false)

	entriesC := make(chan [2]string)
	mocks.kvstore.EXPECT().Iterate(gomock.Eq("test"), gomock.Eq("")).Return(entriesC)
	close(entriesC)
	mocks.kvstore.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any()).Times(4)

	err := conn.Start()
	a.NoError(err)

	routes := make([]*router.Route, 0, 4)
	mocks.router.EXPECT().Subscribe(gomock.Any()).Do(func(r *router.Route) (*router.Route, error) {
		routes = append(routes, r)
		return r, nil
	}).Times(4)

	// create subscriptions
	createSubscriptions(t, conn, 4)
	time.Sleep(100 * time.Millisecond)

	mocks.sender.EXPECT().Send(gomock.Any()).Return(nil, nil).Times(4)

	// send message in route channel
	for i, r := range routes {
		r.Deliver(&protocol.Message{
			ID:   uint64(i),
			Path: protocol.Path("/topic"),
			Body: []byte("test body"),
		})
	}

	time.Sleep(100 * time.Millisecond)

	err = conn.Stop()
	a.NoError(err)
}
Ejemplo n.º 7
0
func TestFullUpdateFlow(t *testing.T) {
	u, ctrl, cfg, mockfs, mockacs, mockhttp := mocks(t, nil)
	defer ctrl.Finish()

	var writtenFile bytes.Buffer
	gomock.InOrder(
		mockhttp.EXPECT().RoundTrip(mock_http.NewHTTPSimpleMatcher("GET", "https://s3.amazonaws.com/amazon-ecs-agent/update.tar")).Return(mock_http.SuccessResponse("update-tar-data"), nil),
		mockfs.EXPECT().Create(gomock.Any()).Return(mock_os.NopReadWriteCloser(&writtenFile), nil),
		mockfs.EXPECT().WriteFile("/tmp/test/desired-image", gomock.Any(), gomock.Any()).Return(nil),
		mockacs.EXPECT().MakeRequest(gomock.Eq(&ecsacs.AckRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("mid").(*string),
		})),
		mockacs.EXPECT().MakeRequest(gomock.Eq(&ecsacs.AckRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("mid2").(*string),
		})),
		mockfs.EXPECT().Exit(exitcodes.ExitUpdate),
	)

	u.stageUpdateHandler()(&ecsacs.StageUpdateMessage{
		ClusterArn:           ptr("cluster").(*string),
		ContainerInstanceArn: ptr("containerInstance").(*string),
		MessageId:            ptr("mid").(*string),
		UpdateInfo: &ecsacs.UpdateInfo{
			Location:  ptr("https://s3.amazonaws.com/amazon-ecs-agent/update.tar").(*string),
			Signature: ptr("6caeef375a080e3241781725b357890758d94b15d7ce63f6b2ff1cb5589f2007").(*string),
		},
	})

	if writtenFile.String() != "update-tar-data" {
		t.Error("Incorrect data written")
	}

	u.performUpdateHandler(statemanager.NewNoopStateManager(), engine.NewTaskEngine(cfg))(&ecsacs.PerformUpdateMessage{
		ClusterArn:           ptr("cluster").(*string),
		ContainerInstanceArn: ptr("containerInstance").(*string),
		MessageId:            ptr("mid2").(*string),
		UpdateInfo: &ecsacs.UpdateInfo{
			Location:  ptr("https://s3.amazonaws.com/amazon-ecs-agent/update.tar").(*string),
			Signature: ptr("c54518806ff4d14b680c35784113e1e7478491fe").(*string),
		},
	})
}
Ejemplo n.º 8
0
// Ensure the subscription is started when posting
func TestConnector_PostSubscription(t *testing.T) {
	_, finish := testutil.NewMockCtrl(t)
	defer finish()

	a := assert.New(t)

	recorder := httptest.NewRecorder()
	conn, mocks := getTestConnector(t, Config{
		Name:       "test",
		Schema:     "test",
		Prefix:     "/connector/",
		URLPattern: "/{device_token}/{user_id}/{topic:.*}",
	}, true, false)

	mocks.manager.EXPECT().Load().Return(nil)
	mocks.manager.EXPECT().List().Return(make([]Subscriber, 0))
	err := conn.Start()
	a.NoError(err)
	defer conn.Stop()

	subscriber := NewMockSubscriber(testutil.MockCtrl)
	mocks.manager.EXPECT().Create(gomock.Eq(protocol.Path("/topic1")), gomock.Eq(router.RouteParams{
		"device_token": "device1",
		"user_id":      "user1",
	})).Return(subscriber, nil)

	subscriber.EXPECT().Loop(gomock.Any(), gomock.Any())
	r := router.NewRoute(router.RouteConfig{
		Path: protocol.Path("topic1"),
		RouteParams: router.RouteParams{
			"device_token": "device1",
			"user_id":      "user1",
		},
	})
	subscriber.EXPECT().Route().Return(r)
	mocks.router.EXPECT().Subscribe(gomock.Eq(r)).Return(r, nil)

	req, err := http.NewRequest(http.MethodPost, "/connector/device1/user1/topic1", strings.NewReader(""))
	a.NoError(err)
	conn.ServeHTTP(recorder, req)
	a.Equal(`{"subscribed":"/topic1"}`, recorder.Body.String())
	time.Sleep(100 * time.Millisecond)
}
func TestGetPlansByGroupHandler(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	u := newTestUser(false)
	g := uuid.New()
	u.Groups = []string{g}
	p, _ := newPlan(u, 2016, 6, goals{goal{"Yay!", 0}})
	db := NewMockdb(ctrl)
	db.EXPECT().LoadPlans(gomock.Eq(2016), gomock.Eq(6)).Return(plans{*p}, nil)
	db.EXPECT().LoadAllUsers().Return(users{*u}, nil)

	rec := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/api/groups/plans/2016/6/"+g, nil)
	handler := makePlansByGroupHandler(getPlansByGroupHandler)

	handler(rec, req, u, db)

	if rec.Code != http.StatusOK {
		t.Error("got", rec.Code, "expected", http.StatusOK)
	}
}
Ejemplo n.º 10
0
func TestHandleTokenEndpointRequest(t *testing.T) {
	ctrl := gomock.NewController(t)
	store := internal.NewMockAuthorizeCodeGrantStorage(ctrl)
	chgen := internal.NewMockEnigma(ctrl)
	areq := internal.NewMockAccessRequester(ctrl)
	aresp := internal.NewMockAccessResponder(ctrl)
	//mockcl := internal.NewMockClient(ctrl)
	defer ctrl.Finish()

	h := AuthorizeExplicitGrantTypeHandler{
		Store:  store,
		Enigma: chgen,
	}
	for k, c := range []struct {
		mock      func()
		req       *http.Request
		expectErr error
	}{
		{
			mock: func() {
				areq.EXPECT().GetGrantType().Return("13245678")
			},
		},
		{
			mock: func() {
				areq.EXPECT().GetGrantType().Return("authorization_code")
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, errors.New("foo"))
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{PostForm: url.Values{}},
			mock: func() {
				areq.EXPECT().GetGrantType().Return("authorization_code")
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				areq.EXPECT().GetClient().Return(&client.SecureClient{})

				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)

				store.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).Return(nil, errors.New(""))
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{PostForm: url.Values{}},
			mock: func() {
				areq.EXPECT().GetGrantType().Return("authorization_code")
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				areq.EXPECT().GetClient().Return(&client.SecureClient{})

				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)

				store.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).Return(&fosite.AuthorizeRequest{}, nil)
				store.EXPECT().DeleteAuthorizeCodeSession(gomock.Any()).Return(nil)
				store.EXPECT().CreateAccessTokenSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New(""))
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{PostForm: url.Values{}},
			mock: func() {
				areq.EXPECT().GetGrantType().Return("authorization_code")
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)

				store.EXPECT().DeleteAuthorizeCodeSession(gomock.Any()).Return(nil)
				store.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).Return(&fosite.AuthorizeRequest{}, nil)
				store.EXPECT().CreateAccessTokenSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				store.EXPECT().CreateRefreshTokenSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New(""))
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{PostForm: url.Values{}},
			mock: func() {
				areq.EXPECT().GetGrantType().Return("authorization_code")
				areq.EXPECT().GetGrantedScopes()
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				areq.EXPECT().GetClient().Return(&client.SecureClient{})
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)
				chgen.EXPECT().GenerateChallenge(gomock.Any()).Return(&enigma.Challenge{}, nil)

				aresp.EXPECT().SetAccessToken(gomock.Eq("."))
				aresp.EXPECT().SetTokenType(gomock.Eq("bearer"))
				aresp.EXPECT().SetExtra(gomock.Eq("refresh_token"), gomock.Any())
				aresp.EXPECT().SetExtra(gomock.Eq("expires_in"), gomock.Any())
				aresp.EXPECT().SetExtra(gomock.Eq("state"), gomock.Any())
				aresp.EXPECT().SetExtra(gomock.Eq("scope"), gomock.Any())

				store.EXPECT().DeleteAuthorizeCodeSession(gomock.Any()).Return(nil)
				store.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).Return(&fosite.AuthorizeRequest{}, nil)
				store.EXPECT().CreateAccessTokenSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				store.EXPECT().CreateRefreshTokenSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
		},
	} {
		c.mock()
		err := h.HandleTokenEndpointRequest(nil, c.req, areq, aresp, nil)
		assert.True(t, errors.Is(c.expectErr, err), "%d\n%s\n%s", k, err, c.expectErr)
		t.Logf("Passed test case %d", k)
	}
}
Ejemplo n.º 11
0
func TestNewerUpdateMessages(t *testing.T) {
	u, ctrl, cfg, mockfs, mockacs, mockhttp := mocks(t, nil)
	defer ctrl.Finish()

	var writtenFile bytes.Buffer
	gomock.InOrder(
		mockhttp.EXPECT().RoundTrip(mock_http.NewHTTPSimpleMatcher("GET", "https://s3.amazonaws.com/amazon-ecs-agent/update.tar")).Return(mock_http.SuccessResponse("update-tar-data"), nil),
		mockfs.EXPECT().Create(gomock.Any()).Return(mock_os.NopReadWriteCloser(&writtenFile), nil),
		mockfs.EXPECT().WriteFile("/tmp/test/desired-image", gomock.Any(), gomock.Any()).Return(nil),
		mockacs.EXPECT().MakeRequest(gomock.Eq(&ecsacs.AckRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("StageMID").(*string),
		})),
		mockacs.EXPECT().MakeRequest(&nackRequestMatcher{&ecsacs.NackRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("StageMID").(*string),
			Reason:            ptr("New update arrived: StageMIDNew").(*string),
		}}),
		mockhttp.EXPECT().RoundTrip(mock_http.NewHTTPSimpleMatcher("GET", "https://s3.amazonaws.com/amazon-ecs-agent/new.tar")).Return(mock_http.SuccessResponse("newer-update-tar-data"), nil),
		mockfs.EXPECT().Create(gomock.Any()).Return(mock_os.NopReadWriteCloser(&writtenFile), nil),
		mockfs.EXPECT().WriteFile("/tmp/test/desired-image", gomock.Any(), gomock.Any()).Return(nil),
		mockacs.EXPECT().MakeRequest(gomock.Eq(&ecsacs.AckRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("StageMIDNew").(*string),
		})),
		mockacs.EXPECT().MakeRequest(gomock.Eq(&ecsacs.AckRequest{
			Cluster:           ptr("cluster").(*string),
			ContainerInstance: ptr("containerInstance").(*string),
			MessageId:         ptr("mid2").(*string),
		})),
		mockfs.EXPECT().Exit(exitcodes.ExitUpdate),
	)

	u.stageUpdateHandler()(&ecsacs.StageUpdateMessage{
		ClusterArn:           ptr("cluster").(*string),
		ContainerInstanceArn: ptr("containerInstance").(*string),
		MessageId:            ptr("StageMID").(*string),
		UpdateInfo: &ecsacs.UpdateInfo{
			Location:  ptr("https://s3.amazonaws.com/amazon-ecs-agent/update.tar").(*string),
			Signature: ptr("6caeef375a080e3241781725b357890758d94b15d7ce63f6b2ff1cb5589f2007").(*string),
		},
	})

	if writtenFile.String() != "update-tar-data" {
		t.Error("Incorrect data written")
	}
	writtenFile.Reset()

	// Never perform, make sure a new hash results in a new stage
	u.stageUpdateHandler()(&ecsacs.StageUpdateMessage{
		ClusterArn:           ptr("cluster").(*string),
		ContainerInstanceArn: ptr("containerInstance").(*string),
		MessageId:            ptr("StageMIDNew").(*string),
		UpdateInfo: &ecsacs.UpdateInfo{
			Location:  ptr("https://s3.amazonaws.com/amazon-ecs-agent/new.tar").(*string),
			Signature: ptr("9c6ea7bd7d49f95b6d516517e453b965897109bf8a1d6ff3a6e57287049eb2de").(*string),
		},
	})

	if writtenFile.String() != "newer-update-tar-data" {
		t.Error("Incorrect data written")
	}

	u.performUpdateHandler(statemanager.NewNoopStateManager(), engine.NewTaskEngine(cfg))(&ecsacs.PerformUpdateMessage{
		ClusterArn:           ptr("cluster").(*string),
		ContainerInstanceArn: ptr("containerInstance").(*string),
		MessageId:            ptr("mid2").(*string),
		UpdateInfo: &ecsacs.UpdateInfo{
			Location:  ptr("https://s3.amazonaws.com/amazon-ecs-agent/update.tar").(*string),
			Signature: ptr("c54518806ff4d14b680c35784113e1e7478491fe").(*string),
		},
	})
}
Ejemplo n.º 12
0
func TestHandleAuthorizeEndpointRequest(t *testing.T) {
	ctrl := gomock.NewController(t)
	store := internal.NewMockAuthorizeCodeGrantStorage(ctrl)
	chgen := internal.NewMockEnigma(ctrl)
	areq := internal.NewMockAuthorizeRequester(ctrl)
	aresp := internal.NewMockAuthorizeResponder(ctrl)
	defer ctrl.Finish()

	h := AuthorizeExplicitGrantTypeHandler{
		Store:  store,
		Enigma: chgen,
	}
	for k, c := range []struct {
		mock      func()
		req       *http.Request
		expectErr error
	}{
		{
			mock: func() {
				areq.EXPECT().GetResponseTypes().Return(fosite.Arguments{})
			},
		},
		{
			mock: func() {
				areq.EXPECT().GetResponseTypes().Return(fosite.Arguments{"foo"})
			},
		},
		{
			mock: func() {
				areq.EXPECT().GetResponseTypes().Return(fosite.Arguments{"code"})
				areq.EXPECT().GetClient().Return(&client.SecureClient{Secret: []byte("foosecret")})
				chgen.EXPECT().GenerateChallenge(gomock.Eq([]byte("foosecret"))).Return(nil, fosite.ErrServerError)
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{Form: url.Values{"redirect_uri": {"foobar"}}},
			mock: func() {
				areq.EXPECT().GetResponseTypes().Return(fosite.Arguments{"code"})
				areq.EXPECT().GetClient().Return(&client.SecureClient{Secret: []byte("foosecret")})
				chgen.EXPECT().GenerateChallenge(gomock.Eq([]byte("foosecret"))).Return(&enigma.Challenge{}, nil)
				store.EXPECT().CreateAuthorizeCodeSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(fosite.ErrTemporarilyUnavailable)
			},
			expectErr: fosite.ErrServerError,
		},
		{
			req: &http.Request{Form: url.Values{"redirect_uri": {"foobar"}}},
			mock: func() {
				areq.EXPECT().GetResponseTypes().Return(fosite.Arguments{"code"})
				areq.EXPECT().GetClient().Return(&client.SecureClient{Secret: []byte("foosecret")})
				chgen.EXPECT().GenerateChallenge(gomock.Eq([]byte("foosecret"))).Return(&enigma.Challenge{Key: "foo", Signature: "bar"}, nil)
				store.EXPECT().CreateAuthorizeCodeSession(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				aresp.EXPECT().AddQuery(gomock.Eq("code"), gomock.Eq("foo.bar"))
				aresp.EXPECT().AddQuery(gomock.Eq("scope"), gomock.Any())
				aresp.EXPECT().AddQuery(gomock.Eq("state"), gomock.Any())
				areq.EXPECT().SetResponseTypeHandled(gomock.Eq("code"))
				areq.EXPECT().GetGrantedScopes()
				areq.EXPECT().GetState()
			},
		},
	} {
		c.mock()
		err := h.HandleAuthorizeEndpointRequest(nil, c.req, areq, aresp, nil)
		assert.True(t, errors.Is(c.expectErr, err), "%d\n%s\n%s", k, err, c.expectErr)
		t.Logf("Passed test case %d", k)
	}
}
Ejemplo n.º 13
0
func TestNewAccessRequest(t *testing.T) {
	ctrl := gomock.NewController(t)
	store := internal.NewMockStorage(ctrl)
	client := internal.NewMockClient(ctrl)
	handler := internal.NewMockTokenEndpointHandler(ctrl)
	hasher := internal.NewMockHasher(ctrl)
	defer ctrl.Finish()

	fosite := &Fosite{Store: store, Hasher: hasher}
	for k, c := range []struct {
		header    http.Header
		form      url.Values
		mock      func()
		method    string
		expectErr error
		expect    *AccessRequest
		handlers  TokenEndpointHandlers
	}{
		{
			header:    http.Header{},
			expectErr: ErrInvalidRequest,
			method:    "POST",
			mock:      func() {},
		},
		{
			header: http.Header{},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock:      func() {},
			expectErr: ErrInvalidRequest,
		},
		{
			header: http.Header{},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
				"client_id":  {"foo"},
			},
			expectErr: ErrInvalidRequest,
			mock:      func() {},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "GET",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidRequest,
			mock:      func() {},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrServerError,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError)
			},
			handlers: TokenEndpointHandlers{"a": handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrUnsupportedGrantType,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: TokenEndpointHandlers{"a": handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrUnsupportedGrantType,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) {
					a.SetGrantTypeHandled("bar")
				}).Return(nil)
			},
			handlers: TokenEndpointHandlers{"a": handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) {
					a.SetGrantTypeHandled("foo")
					a.SetScopes([]string{"asdfasdf"})
				}).Return(nil)
			},
			handlers:  TokenEndpointHandlers{"a": handler},
			expectErr: ErrInvalidScope,
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) {
					a.SetGrantTypeHandled("foo")
					a.SetScopes([]string{DefaultRequiredScopeName})
				}).Return(nil)
			},
			handlers: TokenEndpointHandlers{"a": handler},
			expect: &AccessRequest{
				GrantType:        "foo",
				HandledGrantType: []string{"foo"},
				Client:           client,
			},
		},
	} {
		r := &http.Request{
			Header:   c.header,
			PostForm: c.form,
			Form:     c.form,
			Method:   c.method,
		}
		c.mock()
		ctx := NewContext()
		fosite.TokenEndpointHandlers = c.handlers
		ar, err := fosite.NewAccessRequest(ctx, r, &struct{}{})
		is := errors.Is(c.expectErr, err)
		assert.True(t, is, "%d\nwant: %s \ngot: %s", k, c.expectErr, err)
		if !is {
			t.Logf("Error occured: %s", err.(*errors.Error).ErrorStack())
		}
		if err == nil {
			pkg.AssertObjectKeysEqual(t, c.expect, ar, "GrantType", "Client")
			assert.NotNil(t, ar.GetRequestedAt())
		}
		t.Logf("Passed test case %d", k)
	}
}
Ejemplo n.º 14
0
func Test_SendOneSms(t *testing.T) {
	ctrl, finish := testutil.NewMockCtrl(t)
	defer finish()

	defer testutil.EnableDebugForMethod()()
	a := assert.New(t)

	mockSmsSender := NewMockSender(ctrl)
	kvStore := kvstore.NewMemoryKVStore()

	a.NotNil(kvStore)
	routerMock := NewMockRouter(testutil.MockCtrl)
	routerMock.EXPECT().KVStore().AnyTimes().Return(kvStore, nil)
	msgStore := dummystore.New(kvStore)
	routerMock.EXPECT().MessageStore().AnyTimes().Return(msgStore, nil)

	topic := "/sms"
	worker := 1
	config := Config{
		Workers:  &worker,
		SMSTopic: &topic,
		Name:     "test_gateway",
		Schema:   SMSSchema,
	}

	routerMock.EXPECT().Subscribe(gomock.Any()).Do(func(r *router.Route) (*router.Route, error) {
		a.Equal(topic, string(r.Path))
		return r, nil
	})

	gw, err := New(routerMock, mockSmsSender, config)
	a.NoError(err)

	err = gw.Start()
	a.NoError(err)

	sms := NexmoSms{
		To:   "toNumber",
		From: "FromNUmber",
		Text: "body",
	}
	d, err := json.Marshal(&sms)
	a.NoError(err)

	msg := protocol.Message{
		Path: protocol.Path(topic),
		ID:   uint64(4),
		Body: d,
	}

	mockSmsSender.EXPECT().Send(gomock.Eq(&msg)).Return(nil)
	a.NotNil(gw.route)
	gw.route.Deliver(&msg)
	time.Sleep(100 * time.Millisecond)

	err = gw.Stop()
	a.NoError(err)

	err = gw.ReadLastID()
	a.NoError(err)

	time.Sleep(100 * time.Millisecond)
}
Ejemplo n.º 15
0
func Test_Restart(t *testing.T) {
	ctrl, finish := testutil.NewMockCtrl(t)
	defer finish()
	defer testutil.EnableDebugForMethod()()
	a := assert.New(t)

	mockSmsSender := NewMockSender(ctrl)
	kvStore := kvstore.NewMemoryKVStore()

	a.NotNil(kvStore)
	routerMock := NewMockRouter(testutil.MockCtrl)
	routerMock.EXPECT().KVStore().AnyTimes().Return(kvStore, nil)
	msgStore := NewMockMessageStore(ctrl)
	routerMock.EXPECT().MessageStore().AnyTimes().Return(msgStore, nil)

	topic := "/sms"
	worker := 1
	config := Config{
		Workers:  &worker,
		SMSTopic: &topic,
		Name:     "test_gateway",
		Schema:   SMSSchema,
	}

	routerMock.EXPECT().Subscribe(gomock.Any()).Do(func(r *router.Route) (*router.Route, error) {
		a.Equal(strings.Split(topic, "/")[1], r.Path.Partition())
		return r, nil
	}).Times(2)

	gw, err := New(routerMock, mockSmsSender, config)
	a.NoError(err)

	err = gw.Start()
	a.NoError(err)

	sms := NexmoSms{
		To:   "toNumber",
		From: "FromNUmber",
		Text: "body",
	}
	d, err := json.Marshal(&sms)
	a.NoError(err)

	msg := protocol.Message{
		Path:          protocol.Path(topic),
		UserID:        "samsa",
		ApplicationID: "sms",
		ID:            uint64(4),
		Body:          d,
	}

	//TODO MARIAN  FIX THIS TEST
	//msgStore.EXPECT().MaxMessageID(gomock.Eq(gw.route.Path.Partition())).Return(uint64(0), nil)
	//msgStore.EXPECT().MaxMessageID(gomock.Eq(gw.route.Path.Partition())).Return(uint64(4), nil)
	//msgStore.EXPECT().MaxMessageID(gomock.Eq(gw.route.Path.Partition())).Return(uint64(4), nil)
	mockSmsSender.EXPECT().Send(gomock.Eq(&msg)).Times(1).Return(ErrNoSMSSent)

	//routerMock.EXPECT().Fetch(gomock.Any()).Do(func(r *store.FetchRequest) {
	//	go func() {
	//
	//		logger.WithField("r.Partition", r.Partition).Info("----")
	//
	//		a.Equal(strings.Split(topic, "/")[1], r.Partition)
	//
	//		r.StartC <- 1
	//
	//		r.MessageC <- &store.FetchedMessage{ID: uint64(4), Message: msg.Bytes()}
	//		close(r.MessageC)
	//	}()
	//})
	doneC := make(chan bool)
	routerMock.EXPECT().Done().AnyTimes().Return(doneC)
	//
	//mockSmsSender.EXPECT().Send(gomock.Eq(&msg)).Return(nil)

	a.NotNil(gw.route)
	gw.route.Deliver(&msg)
	time.Sleep(100 * time.Millisecond)
}
Ejemplo n.º 16
0
func TestNewRevocationRequest(t *testing.T) {
	ctrl := gomock.NewController(t)
	store := internal.NewMockStorage(ctrl)
	client := internal.NewMockClient(ctrl)
	handler := internal.NewMockRevocationHandler(ctrl)
	hasher := internal.NewMockHasher(ctrl)
	defer ctrl.Finish()

	fosite := &Fosite{Store: store, Hasher: hasher}
	for k, c := range []struct {
		header    http.Header
		form      url.Values
		mock      func()
		method    string
		expectErr error
		expect    *AccessRequest
		handlers  RevocationHandlers
	}{
		{
			header:    http.Header{},
			expectErr: ErrInvalidRequest,
			method:    "GET",
			mock:      func() {},
		},
		{
			header:    http.Header{},
			expectErr: ErrInvalidRequest,
			method:    "POST",
			mock:      func() {},
		},
		{
			header: http.Header{},
			method: "POST",
			form: url.Values{
				"token": {"foo"},
			},
			mock:      func() {},
			expectErr: ErrInvalidRequest,
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token": {"foo"},
			},
			expectErr: nil,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().RevokeToken(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: RevocationHandlers{handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token":           {"foo"},
				"token_type_hint": {"access_token"},
			},
			expectErr: nil,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().RevokeToken(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: RevocationHandlers{handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token":           {"foo"},
				"token_type_hint": {"refresh_token"},
			},
			expectErr: nil,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().RevokeToken(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: RevocationHandlers{handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"token":           {"foo"},
				"token_type_hint": {"bar"},
			},
			expectErr: nil,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().RevokeToken(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: RevocationHandlers{handler},
		},
	} {
		r := &http.Request{
			Header:   c.header,
			PostForm: c.form,
			Form:     c.form,
			Method:   c.method,
		}
		c.mock()
		ctx := NewContext()
		fosite.RevocationHandlers = c.handlers
		err := fosite.NewRevocationRequest(ctx, r)
		assert.True(t, errors.Cause(err) == c.expectErr, "%d\nwant: %s \ngot: %s", k, c.expectErr, err)
		if err != nil {
			t.Logf("Error occured: %v", err)
		}
		t.Logf("Passed test case %d", k)
	}
}
Ejemplo n.º 17
0
func oauth2TestAuthorizeCodeWorkFlow(oauth2 OAuth2Provider, t *testing.T, refreshMocks func()) {
	const workingClientID = "foo"
	const workingClientSecret = "secretsecretsecretsecret"
	const state = "secure-random-state"

	var workingClientHashedSecret = []byte("$2a$10$rUQDYblu3fytMb9aQ3soh.yKNe.17spWcY9fUkkvI9Nv7U1NJCMV2")
	var session = &struct {
		UserID string
	}{
		UserID: "foo",
	}

	router := mux.NewRouter()
	router.HandleFunc("/auth", authEndpoint(t, oauth2, session))
	router.HandleFunc("/cb", cbEndpoint(t))
	router.HandleFunc("/token", tokenEndpoint(t, oauth2))
	ts = httptest.NewServer(router)
	defer ts.Close()

	for k, c := range []struct {
		conf               goauth2.Config
		state              string
		expectBody         string
		expectStatusCode   int
		expectPath         string
		expectedTokenError bool
		mock               func()
	}{
		{
			conf: goauth2.Config{
				ClientID:     clientID,
				ClientSecret: clientSecret,
				RedirectURL:  ts.URL + "/cb",
				Endpoint: goauth2.Endpoint{
					AuthURL: ts.URL + "/auth",
				},
			},
			state: state,
			mock: func() {
				mockStore.EXPECT().GetClient(gomock.Eq(clientID)).AnyTimes().Return(nil, errors.New("foo"))

				mockClient.EXPECT().GetHashedSecret().AnyTimes().Return(workingClientHashedSecret)
				mockClient.EXPECT().GetRedirectURIs().AnyTimes().Return([]string{ts.URL + "/cb"})

				mockAuthStore.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil, errors.New("foo"))
			},
			expectStatusCode:   http.StatusOK,
			expectPath:         "/auth",
			expectBody:         "{\n\t\"name\": \"invalid_client\",\n\t\"description\": \"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)\"\n}",
			expectedTokenError: true,
		},
		{
			conf: goauth2.Config{
				ClientID:     clientID,
				ClientSecret: clientSecret,
				RedirectURL:  ts.URL + "/cb",
				Endpoint: goauth2.Endpoint{
					AuthURL:  ts.URL + "/auth",
					TokenURL: ts.URL + "/token",
				},
			},
			state: state,
			mock: func() {
				mockStore.EXPECT().GetClient(gomock.Eq(clientID)).AnyTimes().Return(mockClient, nil)

				mockHasher.EXPECT().Compare(gomock.Any(), gomock.Any()).Return(nil)

				mockClient.EXPECT().GetHashedSecret().AnyTimes().Return(workingClientHashedSecret)
				mockClient.EXPECT().GetRedirectURIs().AnyTimes().Return([]string{ts.URL + "/cb"})

				mockAuthStore.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil, errors.New("foo"))
			},
			expectStatusCode:   http.StatusOK,
			expectPath:         "/cb",
			expectBody:         "error: invalid_scope",
			expectedTokenError: true,
		},
		{
			conf: goauth2.Config{
				ClientID:     clientID,
				ClientSecret: clientSecret,
				Scopes:       []string{DefaultRequiredScopeName},
				RedirectURL:  ts.URL + "/cb",
				Endpoint: goauth2.Endpoint{
					AuthURL:  ts.URL + "/auth",
					TokenURL: ts.URL + "/token",
				},
			},
			state: state,
			mock: func() {
				mockStore.EXPECT().GetClient(gomock.Eq(clientID)).AnyTimes().Return(mockClient, nil)

				mockHasher.EXPECT().Compare(gomock.Any(), gomock.Any()).Return(nil)

				mockClient.EXPECT().GetHashedSecret().AnyTimes().Return(workingClientHashedSecret)
				mockClient.EXPECT().GetRedirectURIs().AnyTimes().Return([]string{ts.URL + "/cb"})

				mockAuthStore.EXPECT().CreateAuthorizeCodeSession(gomock.Any(), gomock.Any()).Return(nil)
				mockAuthStore.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil, errors.New("foo"))
			},
			expectStatusCode:   http.StatusOK,
			expectPath:         "/cb",
			expectBody:         "code: ok",
			expectedTokenError: true,
		},
		{
			conf: goauth2.Config{
				ClientID:     clientID,
				ClientSecret: clientSecret,
				RedirectURL:  ts.URL + "/cb",
				Scopes:       []string{DefaultRequiredScopeName},
				Endpoint: goauth2.Endpoint{
					AuthURL:  ts.URL + "/auth",
					TokenURL: ts.URL + "/token",
				},
			},
			state: state,
			mock: func() {
				mockStore.EXPECT().GetClient(gomock.Eq(clientID)).AnyTimes().Return(mockClient, nil)

				mockHasher.EXPECT().Compare(gomock.Any(), gomock.Any()).Return(nil)

				mockClient.EXPECT().GetID().AnyTimes().Return(clientID)
				mockClient.EXPECT().GetHashedSecret().AnyTimes().Return(workingClientHashedSecret)
				mockClient.EXPECT().GetRedirectURIs().AnyTimes().Return([]string{ts.URL + "/cb"})

				mockAuthStore.EXPECT().CreateAuthorizeCodeSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil)
				mockAuthStore.EXPECT().GetAuthorizeCodeSession(gomock.Any(), gomock.Any()).AnyTimes().Return(mockAuthReq, nil)
				mockAuthStore.EXPECT().CreateAccessTokenSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil)
				mockAuthStore.EXPECT().CreateRefreshTokenSession(gomock.Any(), gomock.Any()).AnyTimes().Return(nil)
				mockAuthStore.EXPECT().DeleteAuthorizeCodeSession(gomock.Any()).AnyTimes().Return(nil)

				mockAuthReq.EXPECT().GetClient().AnyTimes().Return(mockClient)
				mockAuthReq.EXPECT().GetRequestedAt().AnyTimes().Return(time.Now())
				mockAuthReq.EXPECT().GetRequestForm().AnyTimes().Return(url.Values{})
				mockAuthReq.EXPECT().GetSession().AnyTimes().Return(nil)
				mockAuthReq.EXPECT().GetScopes().Return([]string{DefaultRequiredScopeName})
			},
			expectStatusCode:   http.StatusOK,
			expectPath:         "/cb",
			expectBody:         "code: ok",
			expectedTokenError: false,
		},

		// TODO add a ton of tests for RFC conform tests. use factories! See https://github.com/ory-am/fosite/issues/13
	} {
		refreshMocks()
		c.mock()
		authurl := c.conf.AuthCodeURL(c.state)
		req := gorequest.New()
		resp, body, errs := req.Get(authurl).End()
		require.Len(t, errs, 0, "%s", errs)
		assert.Equal(t, c.expectPath, resp.Request.URL.Path)
		assert.Equal(t, c.expectBody, body)
		assert.Equal(t, c.expectStatusCode, resp.StatusCode)

		authorizeCode := resp.Request.URL.Query().Get("code")
		token, err := c.conf.Exchange(context.Background(), authorizeCode)
		assert.Equal(t, c.expectedTokenError, err != nil, "%d: %s", k, err)
		if !c.expectedTokenError {
			assert.NotNil(t, token)
		}
		t.Logf("Got token %s", token)
		t.Logf("Passed test case %d", k)
	}
}
func TestNewAccessRequest(t *testing.T) {
	ctrl := gomock.NewController(t)
	store := internal.NewMockStorage(ctrl)
	client := internal.NewMockClient(ctrl)
	handler := internal.NewMockTokenEndpointHandler(ctrl)
	hasher := internal.NewMockHasher(ctrl)
	defer ctrl.Finish()

	fosite := &Fosite{Store: store, Hasher: hasher}
	for k, c := range []struct {
		header    http.Header
		form      url.Values
		mock      func()
		method    string
		expectErr error
		expect    *AccessRequest
		handlers  TokenEndpointHandlers
	}{
		{
			header:    http.Header{},
			expectErr: ErrInvalidRequest,
			method:    "POST",
			mock:      func() {},
		},
		{
			header: http.Header{},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock:      func() {},
			expectErr: ErrInvalidRequest,
		},
		{
			header: http.Header{},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
				"client_id":  {"foo"},
			},
			expectErr: ErrInvalidRequest,
			mock:      func() {},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "GET",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidRequest,
			mock:      func() {},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrInvalidClient,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().IsPublic().Return(false)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(errors.New(""))
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			expectErr: ErrServerError,
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().IsPublic().Return(false)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError)
			},
			handlers: TokenEndpointHandlers{handler},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().IsPublic().Return(false)
				client.EXPECT().GetHashedSecret().Return([]byte("foo"))
				hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
				handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: TokenEndpointHandlers{handler},
			expect: &AccessRequest{
				GrantTypes: Arguments{"foo"},
				Request: Request{
					Client: client,
				},
			},
		},
		{
			header: http.Header{
				"Authorization": {basicAuth("foo", "bar")},
			},
			method: "POST",
			form: url.Values{
				"grant_type": {"foo"},
			},
			mock: func() {
				store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil)
				client.EXPECT().IsPublic().Return(true)
				handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
			},
			handlers: TokenEndpointHandlers{handler},
			expect: &AccessRequest{
				GrantTypes: Arguments{"foo"},
				Request: Request{
					Client: client,
				},
			},
		},
	} {
		r := &http.Request{
			Header:   c.header,
			PostForm: c.form,
			Form:     c.form,
			Method:   c.method,
		}
		c.mock()
		ctx := NewContext()
		fosite.TokenEndpointHandlers = c.handlers
		ar, err := fosite.NewAccessRequest(ctx, r, new(DefaultSession))
		assert.True(t, errors.Cause(err) == c.expectErr, "%d\nwant: %s \ngot: %s", k, c.expectErr, err)
		if err != nil {
			t.Logf("Error occured: %v", err)
		} else {
			pkg.AssertObjectKeysEqual(t, c.expect, ar, "GrantTypes", "Client")
			assert.NotNil(t, ar.GetRequestedAt())
		}
		t.Logf("Passed test case %d", k)
	}
}
func TestNewAuthorizeResponse(t *testing.T) {
	ctrl := gomock.NewController(t)
	handlers := []*MockAuthorizeEndpointHandler{NewMockAuthorizeEndpointHandler(ctrl)}
	ar := NewMockAuthorizeRequester(ctrl)
	defer ctrl.Finish()

	ctx := context.Background()
	oauth2 := &Fosite{
		AuthorizeEndpointHandlers: AuthorizeEndpointHandlers{"a": handlers[0]},
	}
	duo := &Fosite{
		AuthorizeEndpointHandlers: AuthorizeEndpointHandlers{"a": handlers[0], "b": handlers[0]},
	}
	ar.EXPECT().SetSession(gomock.Eq(struct{}{})).AnyTimes()
	fooErr := errors.New("foo")
	for k, c := range []struct {
		isErr     bool
		mock      func()
		expectErr error
	}{
		{
			mock: func() {
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(fooErr)
			},
			isErr:     true,
			expectErr: fooErr,
		},
		{
			mock: func() {
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				ar.EXPECT().DidHandleAllResponseTypes().Return(true)
			},
			isErr: false,
		},
		{
			mock: func() {
				oauth2 = duo
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				ar.EXPECT().DidHandleAllResponseTypes().Return(true)
			},
			isErr: false,
		},
		{
			mock: func() {
				oauth2 = duo
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
				handlers[0].EXPECT().HandleAuthorizeEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(fooErr)
			},
			isErr:     true,
			expectErr: fooErr,
		},
	} {
		c.mock()
		responder, err := oauth2.NewAuthorizeResponse(ctx, &http.Request{}, ar, struct{}{})
		assert.Equal(t, c.isErr, err != nil, "%d: %s", k, err)
		if err != nil {
			assert.Equal(t, c.expectErr, err, "%d: %s", k, err)
			assert.Nil(t, responder, "%d", k)
		} else {
			assert.NotNil(t, responder, "%d", k)
		}
		t.Logf("Passed test case %d", k)
	}
}