Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions projects/industry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package projects

import (
"context"
"encoding/json"
"fmt"
"net/http"

twapi "github.com/teamwork/twapi-go-sdk"
)

var (
_ twapi.HTTPRequester = (*IndustryListRequest)(nil)
_ twapi.HTTPResponser = (*IndustryListResponse)(nil)
)

// Industry refers to the business sector or market category that a company
// belongs to, such as technology, healthcare, finance, or education. It helps
// provide context about the nature of a company’s work and can be used to
// better organize and filter data across the platform. By associating companies
// and projects with specific industries, Teamwork.com allows teams to gain
// clearer insights, tailor communication, and segment information in ways that
// make it easier to manage relationships and understand the broader business
// landscape in which their clients and partners operate.
type Industry struct {
// ID is the unique identifier of the industry.
ID LegacyNumber `json:"id"`

// Name is the name of the industry.
Name string `json:"name"`
}

// IndustryListRequest represents the request body for loading multiple industries.
//
// Not documented.
type IndustryListRequest struct{}

// NewIndustryListRequest creates a new IndustryListRequest with default values.
func NewIndustryListRequest() IndustryListRequest {
return IndustryListRequest{}
}

// HTTPRequest creates an HTTP request for the IndustryListRequest.
func (p IndustryListRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error) {
uri := server + "/industries.json"

req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, err
}
return req, nil
}

// IndustryListResponse contains information by multiple industries matching the
// request filters.
//
// Not documented.
type IndustryListResponse struct {
Industries []Industry `json:"industries"`
}

// HandleHTTPResponse handles the HTTP response for the IndustryListResponse. If
// some unexpected HTTP status code is returned by the API, a twapi.HTTPError is
// returned.
func (p *IndustryListResponse) HandleHTTPResponse(resp *http.Response) error {
if resp.StatusCode != http.StatusOK {
return twapi.NewHTTPError(resp, "failed to list industries")
}

if err := json.NewDecoder(resp.Body).Decode(p); err != nil {
return fmt.Errorf("failed to decode list industries response: %w", err)
}
return nil
}

// IndustryList retrieves multiple industries using the provided request
// and returns the response.
func IndustryList(
ctx context.Context,
engine *twapi.Engine,
req IndustryListRequest,
) (*IndustryListResponse, error) {
return twapi.Execute[IndustryListRequest, *IndustryListResponse](ctx, engine, req)
}
77 changes: 77 additions & 0 deletions projects/industry_example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package projects_test

import (
"context"
"fmt"
"net"
"net/http"
"strings"

twapi "github.com/teamwork/twapi-go-sdk"
"github.com/teamwork/twapi-go-sdk/projects"
"github.com/teamwork/twapi-go-sdk/session"
)

func ExampleIndustryList() {
address, stop, err := startIndustryServer() // mock server for demonstration purposes
if err != nil {
fmt.Printf("failed to start server: %s", err)
return
}
defer stop()

ctx := context.Background()
engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

industryRequest := projects.NewIndustryListRequest()

industryResponse, err := projects.IndustryList(ctx, engine, industryRequest)
if err != nil {
fmt.Printf("failed to list industries: %s", err)
} else {
for _, industry := range industryResponse.Industries {
fmt.Printf("retrieved industry with identifier %d\n", industry.ID)
}
}

// Output: retrieved industry with identifier 12345
// retrieved industry with identifier 12346
}

func startIndustryServer() (string, func(), error) {
ln, err := net.Listen("tcp", "localhost:0")
if err != nil {
return "", nil, fmt.Errorf("failed to start server: %w", err)
}

mux := http.NewServeMux()
mux.HandleFunc("GET /industries", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
_, _ = fmt.Fprintln(w, `{"industries":[{"id":"12345"},{"id":"12346"}]}`)
})

server := &http.Server{
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer your_token" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
mux.ServeHTTP(w, r)
}),
}

stop := make(chan struct{})
go func() {
_ = server.Serve(ln)
}()
go func() {
<-stop
_ = server.Shutdown(context.Background())
}()

return ln.Addr().String(), func() {
close(stop)
}, nil
}
34 changes: 34 additions & 0 deletions projects/industry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package projects_test

import (
"context"
"testing"
"time"

"github.com/teamwork/twapi-go-sdk/projects"
)

func TestIndustryList(t *testing.T) {
if engine == nil {
t.Skip("Skipping test because the engine is not initialized")
}

tests := []struct {
name string
input projects.IndustryListRequest
}{{
name: "all industries",
}}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := t.Context()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
t.Cleanup(cancel)

if _, err := projects.IndustryList(ctx, engine, tt.input); err != nil {
t.Errorf("unexpected error: %s", err)
}
})
}
}