Skip to content

Commit

Permalink
Merge pull request #7 from savannahghi/fetch-facilities
Browse files Browse the repository at this point in the history
feat: fetch facilities
  • Loading branch information
Muchogoc authored Oct 6, 2023
2 parents a1408ff + fce4fe6 commit 5ac5fad
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 22 deletions.
27 changes: 27 additions & 0 deletions healthcrm.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,30 @@ func (h *HealthCRMLib) CreateFacility(ctx context.Context, facility *Facility) (

return facilityResponse, nil
}

// GetFacilities is used to fetch facilities from health crm facility registry
func (h *HealthCRMLib) GetFacilities(ctx context.Context) (*FacilityPage, error) {
path := "/v1/facilities/facilities/"
response, err := h.client.MakeRequest(ctx, http.MethodGet, path, nil, nil)
if err != nil {
return nil, err
}

if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unable to fetch facility(ies) in the registry with status code: %v", response.StatusCode)
}

respBytes, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("could not read response: %w", err)
}

var facilityPage *FacilityPage

err = json.Unmarshal(respBytes, &facilityPage)
if err != nil {
return nil, err
}

return facilityPage, nil
}
100 changes: 96 additions & 4 deletions healthcrm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,11 @@ func TestHealthCRMLib_CreateFacility(t *testing.T) {
Country: "KE",
Address: "",
Coordinates: CoordinatesOutput{
ID: gofakeit.UUID(),
Latitude: 30.4556,
Longitude: 4.54556,
},
Contacts: []Contacts{},
Identifiers: []Identifiers{},
Contacts: []ContactsOutput{},
Identifiers: []IdentifiersOutput{},
BusinessHours: []any{},
}
return httpmock.NewJsonResponse(http.StatusCreated, resp)
Expand Down Expand Up @@ -156,7 +155,7 @@ func TestHealthCRMLib_CreateFacility(t *testing.T) {
MockAuthenticate()
h, err := NewHealthCRMLib()
if err != nil {
t.Errorf("unable to initiLize sdk: %v", err)
t.Errorf("unable to initialize sdk: %v", err)
}
_, err = h.CreateFacility(tt.args.ctx, tt.args.facility)
if (err != nil) != tt.wantErr {
Expand All @@ -166,3 +165,96 @@ func TestHealthCRMLib_CreateFacility(t *testing.T) {
})
}
}

func TestHealthCRMLib_GetFacilities(t *testing.T) {
type args struct {
ctx context.Context
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Happy case: fetch facility(ies)",
args: args{
ctx: context.Background(),
},
wantErr: false,
},
{
name: "Sad case: unable to fetch facility(ies)",
args: args{
ctx: context.Background(),
},
wantErr: true,
},
{
name: "Sad case: unable to make request",
args: args{
ctx: context.Background(),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.name == "Happy case: fetch facility(ies)" {
path := fmt.Sprintf("%s/v1/facilities/facilities/", BaseURL)
httpmock.RegisterResponder(http.MethodGet, path, func(r *http.Request) (*http.Response, error) {
resp := &FacilityOutput{
ID: gofakeit.UUID(),
Name: gofakeit.BeerName(),
Description: gofakeit.HipsterSentence(50),
FacilityType: "HOSPITAL",
County: "Baringo",
Country: "KE",
Address: "",
Coordinates: CoordinatesOutput{
Latitude: 30.4556,
Longitude: 4.54556,
},
Contacts: []ContactsOutput{},
Identifiers: []IdentifiersOutput{},
BusinessHours: []any{},
}
return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

if tt.name == "Sad case: unable to fetch facility(ies)" {
path := fmt.Sprintf("%s/v1/facilities/facilities/", BaseURL)
httpmock.RegisterResponder(http.MethodGet, path, func(r *http.Request) (*http.Response, error) {
return httpmock.NewJsonResponse(http.StatusBadRequest, nil)
})
}

if tt.name == "Sad case: unable to make request" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/oauth2/token/", serverutils.MustGetEnvVar("HEALTH_CRM_AUTH_SERVER_ENDPOINT")), func(r *http.Request) (*http.Response, error) {
resp := authutils.OAUTHResponse{
Scope: "",
ExpiresIn: 3600,
AccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
RefreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
TokenType: "Bearer",
}
return httpmock.NewJsonResponse(http.StatusBadRequest, resp)
})
}

httpmock.Activate()
defer httpmock.DeactivateAndReset()
MockAuthenticate()
h, err := NewHealthCRMLib()
if err != nil {
t.Errorf("unable to initialize sdk: %v", err)
}

_, err = h.GetFacilities(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("HealthCRMLib.GetFacilities() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
3 changes: 0 additions & 3 deletions input.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,19 @@ type Facility struct {

// Coordinates models the geographical's location data class of a facility
type Coordinates struct {
ID string `json:"id"`
Latitude string `json:"latitude"`
Longitude string `json:"longitude"`
}

// Contacts models facility's model data class
type Contacts struct {
ID string `json:"id"`
ContactType string `json:"contact_type"`
ContactValue string `json:"contact_value"`
Role string `json:"role"`
}

// Identifiers models facility's identifiers; can be MFL Code, Slade Code etc...
type Identifiers struct {
ID string `json:"id"`
IdentifierType string `json:"identifier_type"`
IdentifierValue string `json:"identifier_value"`
ValidFrom string `json:"valid_from"`
Expand Down
58 changes: 43 additions & 15 deletions output.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
package healthcrm

import "time"

// Facility is the hospitals model used to show facility details
type FacilityOutput struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
FacilityType string `json:"facility_type"`
County string `json:"county"`
Country string `json:"country"`
Address string `json:"address"`
Coordinates CoordinatesOutput `json:"coordinates"`
Contacts []Contacts `json:"contacts"`
Identifiers []Identifiers `json:"identifiers"`
BusinessHours []any `json:"businesshours"`
type FacilityPage struct {
Count int `json:"count"`
Next string `json:"next"`
Previous any `json:"previous"`
PageSize int `json:"page_size"`
CurrentPage int `json:"current_page"`
TotalPages int `json:"total_pages"`
StartIndex int `json:"start_index"`
EndIndex int `json:"end_index"`
Results []FacilityOutput `json:"results"`
}

// CoordinatesOutput is used to show the geographical's location data class of a facility
type CoordinatesOutput struct {
ID string `json:"id"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
type ContactsOutput struct {
ID string `json:"id"`
ContactType string `json:"contact_type"`
ContactValue string `json:"contact_value"`
Active bool `json:"active"`
Role string `json:"role"`
FacilityID string `json:"facility_id"`
}
type IdentifiersOutput struct {
ID string `json:"id"`
IdentifierType string `json:"identifier_type"`
IdentifierValue string `json:"identifier_value"`
ValidFrom string `json:"valid_from"`
ValidTo string `json:"valid_to"`
FacilityID string `json:"facility_id"`
}
type FacilityOutput struct {
ID string `json:"id"`
Created time.Time `json:"created"`
Name string `json:"name"`
Description string `json:"description"`
FacilityType string `json:"facility_type"`
County string `json:"county"`
Country string `json:"country"`
Coordinates CoordinatesOutput `json:"coordinates"`
Status string `json:"status"`
Address string `json:"address"`
Contacts []ContactsOutput `json:"contacts"`
Identifiers []IdentifiersOutput `json:"identifiers"`
BusinessHours []any `json:"businesshours"`
}

0 comments on commit 5ac5fad

Please sign in to comment.