From edf2ce4ec1dc3773ab5b1d1d588b54c91dfeb8a7 Mon Sep 17 00:00:00 2001 From: antooinerobin Date: Wed, 27 Sep 2023 23:18:38 +0200 Subject: [PATCH 1/3] add first test --- client.go => choruspro.go | 42 +++++++++++++++++++++++++-------------- choruspro_test.go | 32 +++++++++++++++++++++++++++++ examples/main.go | 8 +++++--- transverses_misc.go | 6 +++--- transverses_misc_test.go | 30 ++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 21 deletions(-) rename client.go => choruspro.go (82%) create mode 100644 choruspro_test.go create mode 100644 transverses_misc_test.go diff --git a/client.go b/choruspro.go similarity index 82% rename from client.go rename to choruspro.go index 6756464..ee7fc93 100644 --- a/client.go +++ b/choruspro.go @@ -18,7 +18,7 @@ import ( // ClientConfig contains the configuration for the client type ClientConfig struct { // Piste URL - Url string + BaseUrl string // Piste OAuth URL AuthUrl string @@ -40,10 +40,10 @@ type Client struct { client *http.Client // Piste URL - url string + BaseUrl string // Piste OAuth URL - authUrl string + AuthUrl string // Piste client ID clientId string @@ -68,20 +68,22 @@ type service struct { client *Client } -func NewClient(config *ClientConfig) *Client { - c := &Client{ - client: http.DefaultClient, - url: config.Url, - authUrl: config.AuthUrl, - clientId: config.ClientId, - clientSecret: config.ClientSecret, - login: config.Login, - } - +func NewClient() *Client { + c := &Client{client: http.DefaultClient} c.initialize() return c } +func (c *Client) WithConfig(config *ClientConfig) *Client { + c.BaseUrl = config.BaseUrl + c.AuthUrl = config.AuthUrl + c.clientId = config.ClientId + c.clientSecret = config.ClientSecret + c.login = config.Login + + return c +} + func (c *Client) initialize() { c.common.client = c c.Transverses = (*TransversesService)(&c.common) @@ -90,7 +92,7 @@ func (c *Client) initialize() { func (c *Client) newRequest(ctx context.Context, method, url string, body interface{}) (*http.Request, error) { // Check if token is valid, if not, get a new one if !c.token.Valid() { - token, err := getOAuthToken(c.authUrl, c.clientId, c.clientSecret) + token, err := getOAuthToken(c.AuthUrl, c.clientId, c.clientSecret) if err != nil { return nil, err } @@ -108,7 +110,7 @@ func (c *Client) newRequest(ctx context.Context, method, url string, body interf return nil, err } - req, err := http.NewRequestWithContext(ctx, method, c.url+url, bytes.NewBuffer(data)) + req, err := http.NewRequestWithContext(ctx, method, c.BaseUrl+url, bytes.NewBuffer(data)) if err != nil { return nil, err } @@ -174,6 +176,16 @@ func getOAuthToken(authUrl, clientId, clientSecret string) (*oauth2.Token, error } defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("choruspro: %v", res.Status) + } + + data2, err := io.ReadAll(res.Body) + log.Printf("Response body : \n%s", string(data2)) + if err != nil { + return nil, err + } + err = json.NewDecoder(res.Body).Decode(&token) if err != nil { return nil, err diff --git a/choruspro_test.go b/choruspro_test.go new file mode 100644 index 0000000..a5455e4 --- /dev/null +++ b/choruspro_test.go @@ -0,0 +1,32 @@ +package choruspro + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" +) + +func setup() (client *Client, mux *http.ServeMux, teardown func()) { + mux = http.NewServeMux() + + // OAuth token mock + mux.HandleFunc("/api/oauth/token", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{"access_token":"token","token_type":"Bearer","expires_in":3600}`) + }) + + server := httptest.NewServer(mux) + + client = NewClient() + client.BaseUrl = server.URL + client.AuthUrl = server.URL + "/api/oauth/token" + + return client, mux, server.Close +} + +func testMethod(t *testing.T, r *http.Request, want string) { + if got := r.Method; got != want { + t.Errorf("Request method : %v, got %v", got, want) + } +} diff --git a/examples/main.go b/examples/main.go index 7ba87e7..f50d1b2 100644 --- a/examples/main.go +++ b/examples/main.go @@ -9,13 +9,15 @@ import ( ) func main() { - c := choruspro.NewClient(&choruspro.ClientConfig{ - Url: "", + cfg := &choruspro.ClientConfig{ + BaseUrl: "", AuthUrl: "", ClientId: "", ClientSecret: "", Login: "", - }) + } + + c := choruspro.NewClient().WithConfig(cfg) ctx := context.Background() diff --git a/transverses_misc.go b/transverses_misc.go index 368293d..846f899 100644 --- a/transverses_misc.go +++ b/transverses_misc.go @@ -7,9 +7,9 @@ import ( ) type HealthCheck struct { - Body string `json:"body"` - StatusCodeValue int `json:"statusCodeValue"` - StatusCode string `json:"statusCode"` + Body string `json:"body,omitempty"` + StatusCodeValue int `json:"statusCodeValue,omitempty"` + StatusCode string `json:"statusCode,omitempty"` } func (s *TransversesService) HealthCheck(ctx context.Context) (*HealthCheck, error) { diff --git a/transverses_misc_test.go b/transverses_misc_test.go new file mode 100644 index 0000000..6bb6fe3 --- /dev/null +++ b/transverses_misc_test.go @@ -0,0 +1,30 @@ +package choruspro + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" +) + +func Test(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/health-check", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprint(w, `{"statusCode":"OK"}`) + }) + + ctx := context.Background() + got, err := client.Transverses.HealthCheck(ctx) + if err != nil { + t.Errorf("Transverses.HealthCheck returned error : %v", err) + } + + want := HealthCheck{StatusCode: "200"} + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.HealthCheck returned %+v, want %+v", got, want) + } +} From 86365da5fff8baa3d53c0b34ffd45bb60e8160f1 Mon Sep 17 00:00:00 2001 From: antooinerobin Date: Tue, 3 Oct 2023 23:45:51 +0200 Subject: [PATCH 2/3] transverses_misc fully tested, client adjustements --- choruspro.go | 50 ++-- choruspro_test.go | 32 ++- examples/main.go | 10 +- transverses.go | 4 + transverses_categories.go | 4 +- transverses_etats.go | 4 +- transverses_flux.go | 6 +- transverses_misc.go | 33 ++- transverses_misc_test.go | 515 +++++++++++++++++++++++++++++++++- transverses_pieces_jointes.go | 10 +- transverses_structures.go | 12 +- transverses_tva.go | 4 +- transverses_types.go | 6 +- 13 files changed, 622 insertions(+), 68 deletions(-) diff --git a/choruspro.go b/choruspro.go index ee7fc93..c8b3628 100644 --- a/choruspro.go +++ b/choruspro.go @@ -40,10 +40,10 @@ type Client struct { client *http.Client // Piste URL - BaseUrl string + BaseUrl *url.URL // Piste OAuth URL - AuthUrl string + AuthUrl *url.URL // Piste client ID clientId string @@ -74,14 +74,24 @@ func NewClient() *Client { return c } -func (c *Client) WithConfig(config *ClientConfig) *Client { - c.BaseUrl = config.BaseUrl - c.AuthUrl = config.AuthUrl +func (c *Client) WithConfig(config *ClientConfig) (*Client, error) { + var err error + + c.BaseUrl, err = url.Parse(config.BaseUrl) + if err != nil { + return nil, err + } + + c.AuthUrl, err = url.Parse(config.AuthUrl) + if err != nil { + return nil, err + } + c.clientId = config.ClientId c.clientSecret = config.ClientSecret c.login = config.Login - return c + return c, err } func (c *Client) initialize() { @@ -90,9 +100,18 @@ func (c *Client) initialize() { } func (c *Client) newRequest(ctx context.Context, method, url string, body interface{}) (*http.Request, error) { + if !strings.HasSuffix(c.BaseUrl.Path, "/") { + return nil, fmt.Errorf("BaseURL must have a trailing slash, but %q does not", c.BaseUrl) + } + + u, err := c.BaseUrl.Parse(url) + if err != nil { + return nil, err + } + // Check if token is valid, if not, get a new one if !c.token.Valid() { - token, err := getOAuthToken(c.AuthUrl, c.clientId, c.clientSecret) + token, err := getOAuthToken(c.clientId, c.clientSecret, c.AuthUrl) if err != nil { return nil, err } @@ -110,7 +129,7 @@ func (c *Client) newRequest(ctx context.Context, method, url string, body interf return nil, err } - req, err := http.NewRequestWithContext(ctx, method, c.BaseUrl+url, bytes.NewBuffer(data)) + req, err := http.NewRequestWithContext(ctx, method, u.String(), bytes.NewBuffer(data)) if err != nil { return nil, err } @@ -147,7 +166,12 @@ func (c *Client) doRequest(ctx context.Context, req *http.Request, obj interface return json.Unmarshal(data, obj) } -func getOAuthToken(authUrl, clientId, clientSecret string) (*oauth2.Token, error) { +func getOAuthToken(clientId, clientSecret string, authUrl *url.URL) (*oauth2.Token, error) { + u, err := authUrl.Parse("api/oauth/token") + if err != nil { + return nil, err + } + c := http.DefaultClient data := url.Values{} @@ -157,7 +181,7 @@ func getOAuthToken(authUrl, clientId, clientSecret string) (*oauth2.Token, error encodedData := data.Encode() - req, err := http.NewRequest(http.MethodPost, authUrl+"/api/oauth/token", strings.NewReader(encodedData)) + req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(encodedData)) if err != nil { return nil, err } @@ -180,12 +204,6 @@ func getOAuthToken(authUrl, clientId, clientSecret string) (*oauth2.Token, error return nil, fmt.Errorf("choruspro: %v", res.Status) } - data2, err := io.ReadAll(res.Body) - log.Printf("Response body : \n%s", string(data2)) - if err != nil { - return nil, err - } - err = json.NewDecoder(res.Body).Decode(&token) if err != nil { return nil, err diff --git a/choruspro_test.go b/choruspro_test.go index a5455e4..71a4c15 100644 --- a/choruspro_test.go +++ b/choruspro_test.go @@ -10,7 +10,7 @@ import ( func setup() (client *Client, mux *http.ServeMux, teardown func()) { mux = http.NewServeMux() - // OAuth token mock + // OAuth token mux.HandleFunc("/api/oauth/token", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprint(w, `{"access_token":"token","token_type":"Bearer","expires_in":3600}`) @@ -19,14 +19,40 @@ func setup() (client *Client, mux *http.ServeMux, teardown func()) { server := httptest.NewServer(mux) client = NewClient() - client.BaseUrl = server.URL - client.AuthUrl = server.URL + "/api/oauth/token" + url, _ := client.BaseUrl.Parse(server.URL + "/") + client.BaseUrl = url + client.AuthUrl = url return client, mux, server.Close } +// Test function under s.client.DoRequest failure. +// Method f should be a regular call that would normally succeed, but +// should return an error when NewRequest or s.client.DoRequest fails. +func testDoRequestFailure(t *testing.T, methodName string, client *Client, f func() error) { + t.Helper() + if methodName == "" { + t.Error("testNewRequestAndDoFailure : method name should be provided") + } + + client.BaseUrl.Path = "" + err := f() + + if err == nil { + t.Errorf("client.BaseURL.Path='' %v err = nil, want error", methodName) + } +} + func testMethod(t *testing.T, r *http.Request, want string) { + t.Helper() if got := r.Method; got != want { t.Errorf("Request method : %v, got %v", got, want) } } + +func assertNilError(t *testing.T, err error) { + t.Helper() + if err != nil { + t.Errorf("unexpected error: %v", err) + } +} diff --git a/examples/main.go b/examples/main.go index f50d1b2..0ee3d7b 100644 --- a/examples/main.go +++ b/examples/main.go @@ -17,14 +17,14 @@ func main() { Login: "", } - c := choruspro.NewClient().WithConfig(cfg) + c, err := choruspro.NewClient().WithConfig(cfg) + if err != nil { + log.Fatalf("Error: %v", err) + } ctx := context.Background() - res, err := c.Transverses.ConsulterCompteRendu(ctx, choruspro.CompteRenduOptions{ - NumeroFluxDepot: "", - }) - + res, err := c.Transverses.RecupererDevises(ctx, choruspro.CodeLangueFr) if err != nil { log.Fatalf("Error: %v", err) } diff --git a/transverses.go b/transverses.go index 9af04fb..ddfb9b3 100644 --- a/transverses.go +++ b/transverses.go @@ -9,6 +9,10 @@ const ( CodeLangueEn CodeLangue = "EN" ) +type codeLangueOptions struct { + CodeLangue CodeLangue `json:"codeLangue,omitempty"` +} + type SyntaxeFlux string const ( diff --git a/transverses_categories.go b/transverses_categories.go index ef5a19b..580c575 100644 --- a/transverses_categories.go +++ b/transverses_categories.go @@ -21,7 +21,7 @@ type ListeCategoriesSollicitationOptions struct { } func (s *TransversesService) RechercherCategoriesSollicitation(ctx context.Context, opts ListeCategoriesSollicitationOptions) (*ListeCategoriesSollicitation, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/rechercher/categorieSollicitation", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/rechercher/categorieSollicitation", opts) if err != nil { return nil, err } @@ -70,7 +70,7 @@ type ListeSousCategoriesSollicitationOptions struct { } func (s *TransversesService) RechercherSousCategoriesSollicitation(ctx context.Context, opts ListeSousCategoriesSollicitationOptions) (*ListeSousCategoriesSollicitation, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/rechercher/sousCategorieSollicitation", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/rechercher/sousCategorieSollicitation", opts) if err != nil { return nil, err } diff --git a/transverses_etats.go b/transverses_etats.go index d964b46..2c65cda 100644 --- a/transverses_etats.go +++ b/transverses_etats.go @@ -34,7 +34,7 @@ func (s *TransversesService) RecupererEtatParTypeDemandePaiement(ctx context.Con return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/etat/typedp", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/etat/typedp", opts) if err != nil { return nil, err } @@ -77,7 +77,7 @@ func (s *TransversesService) RecupererEtatsTraitement(ctx context.Context, opts return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/etats/traitement", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/etats/traitement", opts) if err != nil { return nil, err } diff --git a/transverses_flux.go b/transverses_flux.go index 199527f..92238e4 100644 --- a/transverses_flux.go +++ b/transverses_flux.go @@ -21,7 +21,7 @@ type FormatFlux struct { func (s *TransversesService) RecupererFormatFlux(ctx context.Context) (*ListeFormatsFlux, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/formatflux", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/formatflux", opts) if err != nil { return nil, err } @@ -70,7 +70,7 @@ func (s *TransversesService) ConsulterCompteRendu(ctx context.Context, opts Comp return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/consulterCR", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/consulterCR", opts) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (s *TransversesService) ConsulterCompteRenduDetaille(ctx context.Context, o return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/consulterCRDetaille", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/consulterCRDetaille", opts) if err != nil { return nil, err } diff --git a/transverses_misc.go b/transverses_misc.go index 846f899..e351158 100644 --- a/transverses_misc.go +++ b/transverses_misc.go @@ -13,7 +13,7 @@ type HealthCheck struct { } func (s *TransversesService) HealthCheck(ctx context.Context) (*HealthCheck, error) { - req, err := s.client.newRequest(ctx, http.MethodGet, "/cpro/transverses/v1/health-check", nil) + req, err := s.client.newRequest(ctx, http.MethodGet, "cpro/transverses/v1/health-check", nil) if err != nil { return nil, err } @@ -40,11 +40,8 @@ type Devise struct { } func (s *TransversesService) RecupererDevises(ctx context.Context, lang CodeLangue) (*ListeDevises, error) { - opts := &struct { - CodeLangue CodeLangue `json:"codeLangue,omitempty"` - }{CodeLangue: lang} - - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/devises", opts) + opts := &codeLangueOptions{lang} + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/devises", opts) if err != nil { return nil, err } @@ -68,7 +65,7 @@ type AnnuaireDestinataire struct { func (s *TransversesService) TelechargerAnnuaireDestinataire(ctx context.Context) (*AnnuaireDestinataire, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/telecharger/annuaire/destinataire", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/telecharger/annuaire/destinataire", opts) if err != nil { return nil, err } @@ -96,7 +93,7 @@ type ModeDepot struct { func (s *TransversesService) RecupererModesDepot(ctx context.Context) (*ListeModesDepot, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/modedepot", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/modedepot", opts) if err != nil { return nil, err } @@ -123,11 +120,8 @@ type Pays struct { } func (s *TransversesService) RecupererPays(ctx context.Context, lang CodeLangue) (*ListePays, error) { - opts := &struct { - CodeLangue CodeLangue `json:"codeLangue,omitempty"` - }{CodeLangue: lang} - - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/pays", opts) + opts := &codeLangueOptions{lang} + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/pays", opts) if err != nil { return nil, err } @@ -167,7 +161,12 @@ func (o *ListeMotifsRefusFactureAValiderOptions) Validate() error { } func (s *TransversesService) RecupererMotifsRefusFactureAValider(ctx context.Context, opts ListeMotifsRefusFactureAValiderOptions) (*ListeMotifsRefusFactureAValider, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/motifs/refus/Facture/AValider", opts) + err := opts.Validate() + if err != nil { + return nil, err + } + + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/motifs/refus/Facture/AValider", opts) if err != nil { return nil, err } @@ -195,7 +194,7 @@ type ModeReglement struct { func (s *TransversesService) RecupererModesReglement(ctx context.Context) (*ListeModesReglement, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/modereglements", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/modereglements", opts) if err != nil { return nil, err } @@ -225,7 +224,7 @@ func (s *TransversesService) RecupererCadresFacturation(ctx context.Context, typ TypeDemande string `json:"typeDemandePaiement,omitempty"` }{TypeDemande: typeDP} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/cadrefacturation", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/cadrefacturation", opts) if err != nil { return nil, err } @@ -269,7 +268,7 @@ func (s *TransversesService) RecupererCoordonneesBancairesValides(ctx context.Co return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/coordbanc/valides", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/coordbanc/valides", opts) if err != nil { return nil, err } diff --git a/transverses_misc_test.go b/transverses_misc_test.go index 6bb6fe3..be81657 100644 --- a/transverses_misc_test.go +++ b/transverses_misc_test.go @@ -2,19 +2,19 @@ package choruspro import ( "context" - "fmt" + "encoding/json" "net/http" "reflect" "testing" ) -func Test(t *testing.T) { +func TestTransversesService_Healthcheck(t *testing.T) { client, mux, teardown := setup() defer teardown() mux.HandleFunc("/cpro/transverses/v1/health-check", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) - fmt.Fprint(w, `{"statusCode":"OK"}`) + w.Write([]byte(`{"statusCode":"200"}`)) }) ctx := context.Background() @@ -23,8 +23,515 @@ func Test(t *testing.T) { t.Errorf("Transverses.HealthCheck returned error : %v", err) } - want := HealthCheck{StatusCode: "200"} + want := &HealthCheck{StatusCode: "200"} if !reflect.DeepEqual(got, want) { t.Errorf("Transverses.HealthCheck returned %+v, want %+v", got, want) } + + testDoRequestFailure(t, "HealthCheck", client, func() error { + _, err := client.Transverses.HealthCheck(ctx) + return err + }) +} + +func TestTransversesService_RecupererDevises_FR(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/devises", func(w http.ResponseWriter, r *http.Request) { + v := new(codeLangueOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listeDevises": [ + { + "codeDevise": "EUR", + "libelleDevise": "Euro européen" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererDevises(ctx, CodeLangueFr) + if err != nil { + t.Errorf("Transverses.RecupererDevises returned error : %v", err) + } + + want := &ListeDevises{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Devises: []Devise{{ + Code: "EUR", + Libelle: "Euro européen", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererDevises returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererDevises", client, func() error { + _, err := client.Transverses.RecupererDevises(ctx, "") + return err + }) +} + +func TestTransversesService_RecupererDevises_EN(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/devises", func(w http.ResponseWriter, r *http.Request) { + v := new(codeLangueOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listeDevises": [ + { + "codeDevise": "EUR", + "libelleDevise": "European Euro" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererDevises(ctx, CodeLangueEn) + if err != nil { + t.Errorf("Transverses.RecupererDevises returned error : %v", err) + } + + want := &ListeDevises{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Devises: []Devise{{ + Code: "EUR", + Libelle: "European Euro", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererDevises returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererDevises", client, func() error { + _, err := client.Transverses.RecupererDevises(ctx, "") + return err + }) +} + +func TestTransversesService_TelechargerAnnuaireDestinataire(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/telecharger/annuaire/destinataire", func(w http.ResponseWriter, r *http.Request) { + v := new(struct{}) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "GCU_MSG_01_000", + "fichierResultat": "UEsDBBQACAgIAFQYQ1" + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.TelechargerAnnuaireDestinataire(ctx) + if err != nil { + t.Errorf("Transverses.TelechargerAnnuaireDestinataire returned error : %v", err) + } + + want := &AnnuaireDestinataire{ + CodeRetour: 0, + Libelle: "GCU_MSG_01_000", + Fichier: "UEsDBBQACAgIAFQYQ1", + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.TelechargerAnnuaireDestinataire returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "TelechargerAnnuaireDestinataire", client, func() error { + _, err := client.Transverses.TelechargerAnnuaireDestinataire(ctx) + return err + }) +} + +func TestTransversesService_RecupererModesDepot(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/modedepot", func(w http.ResponseWriter, r *http.Request) { + v := new(struct{}) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listeModeDepot": [ + { + "modeDepot": "SAISIE_WEB" + }, + { + "modeDepot": "PORTAIL_PDF" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererModesDepot(ctx) + if err != nil { + t.Errorf("Transverses.RecupererModesDepot returned error : %v", err) + } + + want := &ListeModesDepot{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + ModesDepot: []ModeDepot{{ + ModeDepot: "SAISIE_WEB", + }, { + ModeDepot: "PORTAIL_PDF", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererModesDepot returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererModesDepot", client, func() error { + _, err := client.Transverses.RecupererModesDepot(ctx) + return err + }) +} + +func TestTransversesService_RecupererPays_FR(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/pays", func(w http.ResponseWriter, r *http.Request) { + v := new(codeLangueOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listePays": [ + { + "codePays": "AD", + "libellePays": "Andorre" + }, + { + "codePays": "FR", + "libellePays": "France" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererPays(ctx, CodeLangueFr) + if err != nil { + t.Errorf("Transverses.RecupererPays returned error : %v", err) + } + + want := &ListePays{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Pays: []Pays{{ + Code: "AD", + Libelle: "Andorre", + }, { + Code: "FR", + Libelle: "France", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererPays returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererPays", client, func() error { + _, err := client.Transverses.RecupererPays(ctx, "") + return err + }) +} + +func TestTransversesService_RecupererPays_EN(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/pays", func(w http.ResponseWriter, r *http.Request) { + v := new(codeLangueOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listePays": [ + { + "codePays": "AD", + "libellePays": "Andorra" + }, + { + "codePays": "FR", + "libellePays": "France" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererPays(ctx, CodeLangueEn) + if err != nil { + t.Errorf("Transverses.RecupererPays returned error : %v", err) + } + + want := &ListePays{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Pays: []Pays{{ + Code: "AD", + Libelle: "Andorra", + }, { + Code: "FR", + Libelle: "France", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererPays returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererPays", client, func() error { + _, err := client.Transverses.RecupererPays(ctx, "") + return err + }) +} + +func TestTransversesService_RecupererMotifsRefusFactureAValider(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/motifs/refus/Facture/AValider", func(w http.ResponseWriter, r *http.Request) { + v := new(ListeMotifsRefusFactureAValiderOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listeMotifRefusFactureAValider": [ + { + "idMotif": 1, + "codeMotif": "c1", + "libelleMotif": "l1" + }, + { + "idMotif": 2, + "codeMotif": "c2", + "libelleMotif": "l2" + } + ] + }`)) + }) + + ctx := context.Background() + opt := ListeMotifsRefusFactureAValiderOptions{"c"} + got, err := client.Transverses.RecupererMotifsRefusFactureAValider(ctx, opt) + + if err != nil { + t.Errorf("Transverses.RecupererMotifsRefusFactureAValider returned error : %v", err) + } + + want := &ListeMotifsRefusFactureAValider{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Motifs: []MotifRefus{{ + Id: 1, + Code: "c1", + Libelle: "l1", + }, { + Id: 2, + Code: "c2", + Libelle: "l2", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererMotifsRefusFactureAValider returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererMotifsRefusFactureAValider", client, func() error { + _, err := client.Transverses.RecupererMotifsRefusFactureAValider(ctx, opt) + return err + }) +} + +func TestTransversesService_RecupererMotifsRefusFactureAValider_MissingOption(t *testing.T) { + client, _, _ := setup() + + ctx := context.Background() + opt := ListeMotifsRefusFactureAValiderOptions{} + _, err := client.Transverses.RecupererMotifsRefusFactureAValider(ctx, opt) + + if err == nil { + t.Errorf("Transverses.RecupererMotifsRefusFactureAValider returned error: nil") + } +} + +func TestTransversesService_RecupererModesReglement(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/modereglements", func(w http.ResponseWriter, r *http.Request) { + v := new(struct{}) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "GCU_MSG_01_000", + "listeModePaiement": [ + { + "modePaiement": "m1" + }, + { + "modePaiement": "m2" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererModesReglement(ctx) + + if err != nil { + t.Errorf("Transverses.RecupererModesReglement returned error : %v", err) + } + + want := &ListeModesReglement{ + CodeRetour: 0, + Libelle: "GCU_MSG_01_000", + Modes: []ModeReglement{{ + ModeReglement: "m1", + }, { + ModeReglement: "m2", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererModesReglement returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererModesReglement", client, func() error { + _, err := client.Transverses.RecupererModesReglement(ctx) + return err + }) +} + +func TestTransversesService_RecupererCadresFacturation(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/cadrefacturation", func(w http.ResponseWriter, r *http.Request) { + v := new(struct{}) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "TRA_MSG_00.000", + "listeCadreFacturation": [ + { + "codeCadreFacturation": "c1" + }, + { + "codeCadreFacturation": "c2" + } + ] + }`)) + }) + + ctx := context.Background() + got, err := client.Transverses.RecupererCadresFacturation(ctx, "") + + if err != nil { + t.Errorf("Transverses.RecupererCadresFacturation returned error : %v", err) + } + + want := &ListeCadresFacturation{ + CodeRetour: 0, + Libelle: "TRA_MSG_00.000", + Cadres: []CadreFacturation{{ + Code: "c1", + }, { + Code: "c2", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererCadresFacturation returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererCadresFacturation", client, func() error { + _, err := client.Transverses.RecupererCadresFacturation(ctx, "") + return err + }) +} + +func TestTransversesService_RecupererCoordonneesBancairesValides(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/cpro/transverses/v1/recuperer/coordbanc/valides", func(w http.ResponseWriter, r *http.Request) { + v := new(ListeCoordonneesBancairesOptions) + assertNilError(t, json.NewDecoder(r.Body).Decode(v)) + testMethod(t, r, http.MethodPost) + w.Write([]byte(`{ + "codeRetour": 0, + "libelle": "GCU_MSG_01_000", + "listeCoordonneeBancaire": [ + { + "idCoordonneeBancaire": 1, + "nomCoordonneeBancaire": "n1" + }, + { + "idCoordonneeBancaire": 2, + "nomCoordonneeBancaire": "n2" + } + ] + }`)) + }) + + ctx := context.Background() + opt := ListeCoordonneesBancairesOptions{1} + got, err := client.Transverses.RecupererCoordonneesBancairesValides(ctx, opt) + + if err != nil { + t.Errorf("Transverses.RecupererCoordonneesBancairesValides returned error : %v", err) + } + + want := &ListeCoordonneesBancaires{ + CodeRetour: 0, + Libelle: "GCU_MSG_01_000", + Coordonnees: []CoordonneesBancaires{{ + Id: 1, + Nom: "n1", + }, { + Id: 2, + Nom: "n2", + }}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Transverses.RecupererCoordonneesBancairesValides returned %+v, want %+v", got, want) + } + + testDoRequestFailure(t, "RecupererCoordonneesBancairesValides", client, func() error { + _, err := client.Transverses.RecupererCoordonneesBancairesValides(ctx, opt) + return err + }) +} + +func TestTransversesService_RecupererCoordonneesBancairesValides_MissingOption(t *testing.T) { + client, _, _ := setup() + + ctx := context.Background() + _, err := client.Transverses.RecupererCoordonneesBancairesValides(ctx, ListeCoordonneesBancairesOptions{}) + + if err == nil { + t.Errorf("Transverses.RecupererCoordonneesBancairesValides returned error: nil") + } } diff --git a/transverses_pieces_jointes.go b/transverses_pieces_jointes.go index 316faf8..dc9f442 100644 --- a/transverses_pieces_jointes.go +++ b/transverses_pieces_jointes.go @@ -58,7 +58,7 @@ type ListeTypesPieceJointeOptions struct { } func (s *TransversesService) RecupererTypesPieceJointe(ctx context.Context, opts ListeTypesPieceJointeOptions) (*ListeTypesPieceJointe, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/typespj", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/typespj", opts) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (o AjouterPieceOptions) Validate() error { } func (s *TransversesService) AjouterPieceJointe(ctx context.Context, opts AjouterPieceOptions) (*AjouterPieceResponse, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/ajouter/fichier", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/ajouter/fichier", opts) if err != nil { return nil, err } @@ -165,7 +165,7 @@ func (s *TransversesService) RechercherPiecesJointesStructure(ctx context.Contex return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/rechercher/pj/structure", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/rechercher/pj/structure", opts) if err != nil { return nil, err } @@ -218,7 +218,7 @@ func (s *TransversesService) RechercherPiecesJointesMonCompte(ctx context.Contex return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/rechercher/pj/moncompte", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/rechercher/pj/moncompte", opts) if err != nil { return nil, err } @@ -348,7 +348,7 @@ func (s *TransversesService) TelechargerPieceJointe(ctx context.Context, opts Te return nil, err } - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/telecharger/pieceJointe", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/telecharger/pieceJointe", opts) if err != nil { return nil, err } diff --git a/transverses_structures.go b/transverses_structures.go index dc736cf..1a55bec 100644 --- a/transverses_structures.go +++ b/transverses_structures.go @@ -21,7 +21,7 @@ type StructureActive struct { func (s *TransversesService) RecupererStructuresActivesFactureTravaux(ctx context.Context) (*ListeStrcturesActives, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/structures/actives/facturetravaux", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/structures/actives/facturetravaux", opts) if err != nil { return nil, err } @@ -39,7 +39,7 @@ func (s *TransversesService) RecupererStructuresActivesFactureTravaux(ctx contex func (s *TransversesService) RecupererStructuresActivesDestinataireFactureTravaux(ctx context.Context) (*ListeStrcturesActives, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/structures/actives/destinataire", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/structures/actives/destinataire", opts) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (s *TransversesService) RecupererStructuresActivesDestinataireFactureTravau func (s *TransversesService) RecupererStructuresActivesFournisseur(ctx context.Context) (*ListeStrcturesActives, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/structures/actives/fournisseur", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/structures/actives/fournisseur", opts) if err != nil { return nil, err } @@ -75,7 +75,7 @@ func (s *TransversesService) RecupererStructuresActivesFournisseur(ctx context.C func (s *TransversesService) RecupererStructuresActivesDestinataire(ctx context.Context) (*ListeStrcturesActives, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/structures/actives/destinataire", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/structures/actives/destinataire", opts) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func (s *TransversesService) ConsulterInformationsSIRET(ctx context.Context, sir SiretStrucutre string `json:"siretStructure"` }{SiretStrucutre: siret} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/consulter/information/siret", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/consulter/information/siret", opts) if err != nil { return nil, err } @@ -158,7 +158,7 @@ type ListeDestinatairesOptions struct { } func (s *TransversesService) RechercherDestinataires(ctx context.Context, opts ListeDestinatairesOptions) (*ListeDestinataires, error) { - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/rechercher/destinataire", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/rechercher/destinataire", opts) if err != nil { return nil, err } diff --git a/transverses_tva.go b/transverses_tva.go index 9212f93..cedb653 100644 --- a/transverses_tva.go +++ b/transverses_tva.go @@ -22,7 +22,7 @@ func (s *TransversesService) RecupererTauxTva(ctx context.Context, lang CodeLang CodeLangue CodeLangue `json:"codeLangue,omitempty"` }{CodeLangue: lang} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/tauxtva", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/tauxtva", opts) if err != nil { return nil, err } @@ -53,7 +53,7 @@ func (s *TransversesService) RecupererMotifsExonerationTva(ctx context.Context, CodeLangue CodeLangue `json:"codeLangue,omitempty"` }{CodeLangue: lang} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/motifs/exonerationtva", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/motifs/exonerationtva", opts) if err != nil { return nil, err } diff --git a/transverses_types.go b/transverses_types.go index 7a8c63e..5dd718e 100644 --- a/transverses_types.go +++ b/transverses_types.go @@ -18,7 +18,7 @@ type TypeDemandePaiement struct { func (s *TransversesService) RecupererTypesDemandePaiement(ctx context.Context) (*ListeTypesDemandePaiement, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/typedp", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/typedp", opts) if err != nil { return nil, err } @@ -46,7 +46,7 @@ type TypeFactureTravaux struct { func (s *TransversesService) RecupererTypesFactureTravaux(ctx context.Context) (*ListeTypesFactureTravaux, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/typefacturetravaux", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/typefacturetravaux", opts) if err != nil { return nil, err } @@ -74,7 +74,7 @@ type TypeIdentifiantStructure struct { func (s *TransversesService) RecupererTypesIdentifiantsStructure(ctx context.Context) (*ListeTypesIdentifiantsStructure, error) { opts := struct{}{} - req, err := s.client.newRequest(ctx, http.MethodPost, "/cpro/transverses/v1/recuperer/typeidentifiant/structure", opts) + req, err := s.client.newRequest(ctx, http.MethodPost, "cpro/transverses/v1/recuperer/typeidentifiant/structure", opts) if err != nil { return nil, err } From ebe415afdc394b0ee0e098621c16ca59b0f79207 Mon Sep 17 00:00:00 2001 From: antooinerobin Date: Tue, 3 Oct 2023 23:52:43 +0200 Subject: [PATCH 3/3] add github actions tests workflow --- .github/workflows/tests.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..df66532 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,26 @@ +name: 'Tests & Code coverage' + +on: + push: + branches: + - master + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + + - uses: actions/checkout@v4 + + - name: Install dependencies + run: go mod download + + - name: Run test and converage + run: go test ./... -v -coverprofile=coverage.out -covermode=atomic + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 \ No newline at end of file