package client import ( "fmt" "net/http" "net/http/httptest" "sort" "testing" "github.com/sparetimecoders/goamqp" "github.com/stretchr/testify/assert" ) func TestPrivilegeHandler_Process_InvalidType(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process("abc", goamqp.Headers{}) assert.Nil(t, result) assert.EqualError(t, err, "unexpected event type: 'string'") } func TestPrivilegeHandler_Process_PrivilegeRemoved(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeAdmin, }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return privileges.Admin }) assert.Equal(t, []string{"abc-123"}, companies) result, err = handler.Process(&PrivilegeRemoved{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeAdmin, }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return privileges.Admin }) assert.Empty(t, companies) } func TestPrivilegeHandler_Process_UserAdded_And_UserRemoved(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process(&UserAdded{ Email: "jim@example.org", CompanyID: "abc-123", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) result, err = handler.Process(&UserAdded{ Email: "jim@example.org", CompanyID: "abc-456", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return true }) sort.Strings(companies) assert.Equal(t, []string{"abc-123", "abc-456"}, companies) result, err = handler.Process(&UserRemoved{ Email: "jim@example.org", CompanyID: "abc-123", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) result, err = handler.Process(&UserRemoved{ Email: "jim@example.org", CompanyID: "abc-456", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return true }) assert.Empty(t, companies) } func TestPrivilegeHandler_GetCompanies_Email_Not_Found(t *testing.T) { handler := New(WithBaseURL("base")) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return true }) assert.Empty(t, companies) } func TestPrivilegeHandler_GetCompanies_No_Companies_Found(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process(&UserAdded{ Email: "jim@example.org", CompanyID: "abc-123", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return privileges.Admin }) assert.Empty(t, companies) companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return true }) assert.Equal(t, []string{"abc-123"}, companies) result, err = handler.Process(&UserRemoved{ Email: "jim@example.org", CompanyID: "abc-123", }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies = handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return true }) assert.Empty(t, companies) } func TestPrivilegeHandler_GetCompanies_Company_With_Company_Access_Found(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeCompany, }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return privileges.Company }) assert.Equal(t, []string{"abc-123"}, companies) } func TestPrivilegeHandler_GetCompanies_Company_With_Admin_Access_Found(t *testing.T) { handler := New(WithBaseURL("base")) result, err := handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeConsumer, }, goamqp.Headers{}) assert.Nil(t, result) assert.NoError(t, err) companies := handler.CompaniesByUser("jim@example.org", func(privileges CompanyPrivileges) bool { return privileges.Consumer }) assert.Equal(t, []string{"abc-123"}, companies) } func TestPrivilegeHandler_IsAllowed_Return_False_If_No_Privileges(t *testing.T) { handler := New(WithBaseURL("base")) result := handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { return privileges.Company }) assert.False(t, result) } func TestPrivilegeHandler_IsAllowed_Return_True_If_Privilege_Exists(t *testing.T) { handler := New(WithBaseURL("base")) _, _ = handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeTime, }, goamqp.Headers{}) result := handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { return privileges.Time }) assert.True(t, result) _, _ = handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeInvoicing, }, goamqp.Headers{}) result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { return privileges.Invoicing }) assert.True(t, result) _, _ = handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeAccounting, }, goamqp.Headers{}) result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { return privileges.Accounting }) assert.True(t, result) _, _ = handler.Process(&PrivilegeAdded{ Email: "jim@example.org", CompanyID: "abc-123", Privilege: PrivilegeSupplier, }, goamqp.Headers{}) result = handler.IsAllowed("jim@example.org", "abc-123", func(privileges CompanyPrivileges) bool { return privileges.Supplier }) assert.True(t, result) } func TestPrivilegeHandler_Fetch_Error_Response(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) baseURL := server.Listener.Addr().String() handler := New(WithBaseURL(fmt.Sprintf("http://%s", baseURL))) server.Close() err := handler.Fetch() assert.EqualError(t, err, fmt.Sprintf("Get \"http://%s/authz\": dial tcp %s: connect: connection refused", baseURL, baseURL)) } func TestPrivilegeHandler_Fetch_Error_Unreadable_Body(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Length", "1") })) defer server.Close() baseURL := server.Listener.Addr().String() handler := New(WithBaseURL(fmt.Sprintf("http://%s", baseURL))) err := handler.Fetch() assert.EqualError(t, err, "unexpected EOF") } func TestPrivilegeHandler_Fetch_Error_Broken_JSON(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("{abc")) })) defer server.Close() baseURL := server.Listener.Addr().String() handler := New(WithBaseURL(fmt.Sprintf("http://%s", baseURL))) err := handler.Fetch() assert.EqualError(t, err, "invalid character 'a' looking for beginning of object key string") } func TestPrivilegeHandler_Fetch_Valid(t *testing.T) { privileges := ` { "jim@example.org": { "00010203-0405-4607-8809-0a0b0c0d0e0f": { "admin": false, "company": true, "consumer": false, "time": true, "invoicing": true, "accounting": false, "supplier": false } } }` server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(privileges)) })) defer server.Close() baseURL := server.Listener.Addr().String() handler := New(WithBaseURL(fmt.Sprintf("http://%s", baseURL))) err := handler.Fetch() assert.NoError(t, err) expectedPrivileges := map[string]map[string]*CompanyPrivileges{ "jim@example.org": { "00010203-0405-4607-8809-0a0b0c0d0e0f": { Admin: false, Company: true, Consumer: false, Time: true, Invoicing: true, Accounting: false, Supplier: false, }, }, } assert.Equal(t, expectedPrivileges, handler.privileges) }