diff --git a/goztl.go b/goztl.go index 359870e..30403d1 100644 --- a/goztl.go +++ b/goztl.go @@ -15,7 +15,7 @@ import ( ) const ( - libraryVersion = "0.1.42" + libraryVersion = "0.1.43" userAgent = "goztl/" + libraryVersion mediaType = "application/json" ) @@ -38,13 +38,14 @@ type Client struct { Tags TagsService Taxonomies TaxonomiesService // MDM - MDMArtifacts MDMArtifactsService - MDMBlueprints MDMBlueprintsService - MDMBlueprintArtifacts MDMBlueprintArtifactsService - MDMEnterpriseApps MDMEnterpriseAppsService - MDMFileVaultConfigs MDMFileVaultConfigsService - MDMProfiles MDMProfilesService - MDMRecoveryPasswordConfigs MDMRecoveryPasswordConfigsService + MDMArtifacts MDMArtifactsService + MDMBlueprints MDMBlueprintsService + MDMBlueprintArtifacts MDMBlueprintArtifactsService + MDMEnterpriseApps MDMEnterpriseAppsService + MDMFileVaultConfigs MDMFileVaultConfigsService + MDMProfiles MDMProfilesService + MDMRecoveryPasswordConfigs MDMRecoveryPasswordConfigsService + MDMSoftwareUpdateEnforcements MDMSoftwareUpdateEnforcementsService // Monolith MonolithCatalogs MonolithCatalogsService MonolithConditions MonolithConditionsService @@ -165,6 +166,7 @@ func NewClient(httpClient *http.Client, bu string, token string, opts ...ClientO c.MDMFileVaultConfigs = &MDMFileVaultConfigsServiceOp{client: c} c.MDMProfiles = &MDMProfilesServiceOp{client: c} c.MDMRecoveryPasswordConfigs = &MDMRecoveryPasswordConfigsServiceOp{client: c} + c.MDMSoftwareUpdateEnforcements = &MDMSoftwareUpdateEnforcementsServiceOp{client: c} // Monolith c.MonolithCatalogs = &MonolithCatalogsServiceOp{client: c} c.MonolithConditions = &MonolithConditionsServiceOp{client: c} diff --git a/mdm_blueprints.go b/mdm_blueprints.go index f07bb97..42689a5 100644 --- a/mdm_blueprints.go +++ b/mdm_blueprints.go @@ -29,16 +29,17 @@ var _ MDMBlueprintsService = &MDMBlueprintsServiceOp{} // MDMBlueprint represents a Zentral MDM blueprint type MDMBlueprint struct { - ID int `json:"id,omitempty"` - Name string `json:"name"` - InventoryInterval int `json:"inventory_interval"` - CollectApps int `json:"collect_apps"` - CollectCertificates int `json:"collect_certificates"` - CollectProfiles int `json:"collect_profiles"` - FileVaultConfigID *int `json:"filevault_config"` - RecoveryPasswordConfigID *int `json:"recovery_password_config"` - Created Timestamp `json:"created_at,omitempty"` - Updated Timestamp `json:"updated_at,omitempty"` + ID int `json:"id,omitempty"` + Name string `json:"name"` + InventoryInterval int `json:"inventory_interval"` + CollectApps int `json:"collect_apps"` + CollectCertificates int `json:"collect_certificates"` + CollectProfiles int `json:"collect_profiles"` + FileVaultConfigID *int `json:"filevault_config"` + RecoveryPasswordConfigID *int `json:"recovery_password_config"` + SoftwareUpdateEnforcementIDs []int `json:"software_update_enforcements"` + Created Timestamp `json:"created_at,omitempty"` + Updated Timestamp `json:"updated_at,omitempty"` } func (mb MDMBlueprint) String() string { @@ -47,13 +48,14 @@ func (mb MDMBlueprint) String() string { // MDMBlueprintRequest represents a request to create or update a MDM blueprint type MDMBlueprintRequest struct { - Name string `json:"name"` - InventoryInterval int `json:"inventory_interval"` - CollectApps int `json:"collect_apps"` - CollectCertificates int `json:"collect_certificates"` - CollectProfiles int `json:"collect_profiles"` - FileVaultConfigID *int `json:"filevault_config"` - RecoveryPasswordConfigID *int `json:"recovery_password_config"` + Name string `json:"name"` + InventoryInterval int `json:"inventory_interval"` + CollectApps int `json:"collect_apps"` + CollectCertificates int `json:"collect_certificates"` + CollectProfiles int `json:"collect_profiles"` + FileVaultConfigID *int `json:"filevault_config"` + RecoveryPasswordConfigID *int `json:"recovery_password_config"` + SoftwareUpdateEnforcementIDs []int `json:"software_update_enforcements"` } type listMBOptions struct { diff --git a/mdm_blueprints_test.go b/mdm_blueprints_test.go index a97bba2..46766ad 100644 --- a/mdm_blueprints_test.go +++ b/mdm_blueprints_test.go @@ -22,6 +22,7 @@ var mbListJSONResponse = ` "collect_profiles": 2, "filevault_config": null, "recovery_password_config": null, + "software_update_enforcements": [], "created_at": "2022-07-22T01:02:03.444444", "updated_at": "2022-07-22T01:02:03.444444" } @@ -38,6 +39,7 @@ var mbGetJSONResponse = ` "collect_profiles": 2, "filevault_config": 3, "recovery_password_config": 4, + "software_update_enforcements": [5], "created_at": "2022-07-22T01:02:03.444444", "updated_at": "2022-07-22T01:02:03.444444" } @@ -51,6 +53,7 @@ var mbCreateJSONResponse = ` "collect_apps": 0, "collect_certificates": 1, "collect_profiles": 2, + "software_update_enforcements": [], "created_at": "2022-07-22T01:02:03.444444", "updated_at": "2022-07-22T01:02:03.444444" } @@ -66,6 +69,7 @@ var mbUpdateJSONResponse = ` "collect_profiles": 2, "filevault_config": 3, "recovery_password_config": 4, + "software_update_enforcements": [5], "created_at": "2022-07-22T01:02:03.444444", "updated_at": "2022-07-22T01:02:03.444444" } @@ -89,14 +93,15 @@ func TestMDMBlueprintsService_List(t *testing.T) { want := []MDMBlueprint{ { - ID: 4, - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - Created: Timestamp{referenceTime}, - Updated: Timestamp{referenceTime}, + ID: 4, + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + SoftwareUpdateEnforcementIDs: []int{}, + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, }, } if !cmp.Equal(got, want) { @@ -121,16 +126,17 @@ func TestMDMBlueprintsService_GetByID(t *testing.T) { } want := &MDMBlueprint{ - ID: 4, - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - FileVaultConfigID: Int(3), - RecoveryPasswordConfigID: Int(4), - Created: Timestamp{referenceTime}, - Updated: Timestamp{referenceTime}, + ID: 4, + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + FileVaultConfigID: Int(3), + RecoveryPasswordConfigID: Int(4), + SoftwareUpdateEnforcementIDs: []int{5}, + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, } if !cmp.Equal(got, want) { t.Errorf("MDMBlueprints.GetByID returned %+v, want %+v", got, want) @@ -155,14 +161,15 @@ func TestMDMBlueprintsService_GetByName(t *testing.T) { } want := &MDMBlueprint{ - ID: 4, - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - Created: Timestamp{referenceTime}, - Updated: Timestamp{referenceTime}, + ID: 4, + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + SoftwareUpdateEnforcementIDs: []int{}, + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, } if !cmp.Equal(got, want) { t.Errorf("MDMBlueprints.GetByName returned %+v, want %+v", got, want) @@ -202,14 +209,15 @@ func TestMDMBlueprintsService_Create(t *testing.T) { } want := &MDMBlueprint{ - ID: 4, - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - Created: Timestamp{referenceTime}, - Updated: Timestamp{referenceTime}, + ID: 4, + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + SoftwareUpdateEnforcementIDs: []int{}, + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, } if !cmp.Equal(got, want) { t.Errorf("MDMBlueprints.Create returned %+v, want %+v", got, want) @@ -221,13 +229,14 @@ func TestMDMBlueprintsService_Update(t *testing.T) { defer teardown() updateRequest := &MDMBlueprintRequest{ - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - FileVaultConfigID: Int(3), - RecoveryPasswordConfigID: Int(4), + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + FileVaultConfigID: Int(3), + RecoveryPasswordConfigID: Int(4), + SoftwareUpdateEnforcementIDs: []int{5}, } mux.HandleFunc("/mdm/blueprints/4/", func(w http.ResponseWriter, r *http.Request) { @@ -250,16 +259,17 @@ func TestMDMBlueprintsService_Update(t *testing.T) { } want := &MDMBlueprint{ - ID: 4, - Name: "Default", - InventoryInterval: 77777, - CollectApps: 0, - CollectCertificates: 1, - CollectProfiles: 2, - FileVaultConfigID: Int(3), - RecoveryPasswordConfigID: Int(4), - Created: Timestamp{referenceTime}, - Updated: Timestamp{referenceTime}, + ID: 4, + Name: "Default", + InventoryInterval: 77777, + CollectApps: 0, + CollectCertificates: 1, + CollectProfiles: 2, + FileVaultConfigID: Int(3), + RecoveryPasswordConfigID: Int(4), + SoftwareUpdateEnforcementIDs: []int{5}, + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, } if !cmp.Equal(got, want) { t.Errorf("MDMBlueprints.Update returned %+v, want %+v", got, want) diff --git a/mdm_software_update_enforcements.go b/mdm_software_update_enforcements.go new file mode 100644 index 0000000..404b909 --- /dev/null +++ b/mdm_software_update_enforcements.go @@ -0,0 +1,202 @@ +package goztl + +import ( + "context" + "fmt" + "net/http" +) + +const msueBasePath = "mdm/software_update_enforcements/" + +// MDMSoftwareUpdateEnforcementsService is an interface for interfacing with the MDM software update enforcement +// endpoints of the Zentral API +type MDMSoftwareUpdateEnforcementsService interface { + List(context.Context, *ListOptions) ([]MDMSoftwareUpdateEnforcement, *Response, error) + GetByID(context.Context, int) (*MDMSoftwareUpdateEnforcement, *Response, error) + GetByName(context.Context, string) (*MDMSoftwareUpdateEnforcement, *Response, error) + Create(context.Context, *MDMSoftwareUpdateEnforcementRequest) (*MDMSoftwareUpdateEnforcement, *Response, error) + Update(context.Context, int, *MDMSoftwareUpdateEnforcementRequest) (*MDMSoftwareUpdateEnforcement, *Response, error) + Delete(context.Context, int) (*Response, error) +} + +// MDMSoftwareUpdateEnforcementsServiceOp handles communication with the MDM software update enforcements related +// methods of the Zentral API. +type MDMSoftwareUpdateEnforcementsServiceOp struct { + client *Client +} + +var _ MDMSoftwareUpdateEnforcementsService = &MDMSoftwareUpdateEnforcementsServiceOp{} + +// MDMSoftwareUpdateEnforcement represents a Zentral MDM software update enforcement +type MDMSoftwareUpdateEnforcement struct { + ID int `json:"id"` + Name string `json:"name"` + DetailsURL string `json:"details_url"` + TagIDs []int `json:"tags"` + OSVersion string `json:"os_version"` + BuildVersion string `json:"build_version"` + LocalDateTime *string `json:"local_datetime"` + MaxOSVersion string `json:"max_os_version"` + DelayDays *int `json:"delay_days"` + LocalTime *string `json:"local_time"` + Created Timestamp `json:"created_at,omitempty"` + Updated Timestamp `json:"updated_at,omitempty"` +} + +func (msue MDMSoftwareUpdateEnforcement) String() string { + return Stringify(msue) +} + +// MDMSoftwareUpdateEnforcementRequest represents a request to create or update a MDM software update enforcement +type MDMSoftwareUpdateEnforcementRequest struct { + Name string `json:"name"` + DetailsURL string `json:"details_url"` + TagIDs []int `json:"tags"` + OSVersion string `json:"os_version"` + BuildVersion string `json:"build_version"` + LocalDateTime *string `json:"local_datetime"` + MaxOSVersion string `json:"max_os_version"` + DelayDays *int `json:"delay_days"` + LocalTime *string `json:"local_time"` +} + +type listMSUEOptions struct { + Name string `url:"name,omitempty"` +} + +// List lists all the MDM software update enforcements. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) List(ctx context.Context, opt *ListOptions) ([]MDMSoftwareUpdateEnforcement, *Response, error) { + return s.list(ctx, opt, nil) +} + +// GetByID retrieves a MDM software update enforcement by id. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) GetByID(ctx context.Context, msueID int) (*MDMSoftwareUpdateEnforcement, *Response, error) { + if msueID < 1 { + return nil, nil, NewArgError("msueID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s%d/", msueBasePath, msueID) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + msue := new(MDMSoftwareUpdateEnforcement) + + resp, err := s.client.Do(ctx, req, msue) + if err != nil { + return nil, resp, err + } + + return msue, resp, err +} + +// GetByName retrieves a MDM software update enforcement by name. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) GetByName(ctx context.Context, name string) (*MDMSoftwareUpdateEnforcement, *Response, error) { + if len(name) < 1 { + return nil, nil, NewArgError("name", "cannot be blank") + } + + listMSUEOpt := &listMSUEOptions{Name: name} + + msues, resp, err := s.list(ctx, nil, listMSUEOpt) + if err != nil { + return nil, resp, err + } + if len(msues) < 1 { + return nil, resp, nil + } + + return &msues[0], resp, err +} + +// Create a new MDM software update enforcement. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) Create(ctx context.Context, createRequest *MDMSoftwareUpdateEnforcementRequest) (*MDMSoftwareUpdateEnforcement, *Response, error) { + if createRequest == nil { + return nil, nil, NewArgError("createRequest", "cannot be nil") + } + + req, err := s.client.NewRequest(ctx, http.MethodPost, msueBasePath, createRequest) + if err != nil { + return nil, nil, err + } + + msue := new(MDMSoftwareUpdateEnforcement) + resp, err := s.client.Do(ctx, req, msue) + if err != nil { + return nil, resp, err + } + + return msue, resp, err +} + +// Update a MDM software update enforcement. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) Update(ctx context.Context, msueID int, updateRequest *MDMSoftwareUpdateEnforcementRequest) (*MDMSoftwareUpdateEnforcement, *Response, error) { + if msueID < 1 { + return nil, nil, NewArgError("msueID", "cannot be less than 1") + } + + if updateRequest == nil { + return nil, nil, NewArgError("updateRequest", "cannot be nil") + } + + path := fmt.Sprintf("%s%d/", msueBasePath, msueID) + + req, err := s.client.NewRequest(ctx, http.MethodPut, path, updateRequest) + if err != nil { + return nil, nil, err + } + + msue := new(MDMSoftwareUpdateEnforcement) + resp, err := s.client.Do(ctx, req, msue) + if err != nil { + return nil, resp, err + } + + return msue, resp, err +} + +// Delete a MDM software update enforcement. +func (s *MDMSoftwareUpdateEnforcementsServiceOp) Delete(ctx context.Context, msueID int) (*Response, error) { + if msueID < 1 { + return nil, NewArgError("msueID", "cannot be less than 1") + } + + path := fmt.Sprintf("%s%d/", msueBasePath, msueID) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + + return resp, err +} + +// Helper method for listing MDM software update enforcements +func (s *MDMSoftwareUpdateEnforcementsServiceOp) list(ctx context.Context, opt *ListOptions, msueOpt *listMSUEOptions) ([]MDMSoftwareUpdateEnforcement, *Response, error) { + path := msueBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + path, err = addOptions(path, msueOpt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + var msues []MDMSoftwareUpdateEnforcement + resp, err := s.client.Do(ctx, req, &msues) + if err != nil { + return nil, resp, err + } + + return msues, resp, err +} diff --git a/mdm_software_update_enforcements_test.go b/mdm_software_update_enforcements_test.go new file mode 100644 index 0000000..4901c50 --- /dev/null +++ b/mdm_software_update_enforcements_test.go @@ -0,0 +1,295 @@ +package goztl + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" +) + +var msueListJSONResponse = ` +[ + { + "id": 4, + "name": "Default", + "details_url": "https://www.example.com", + "tags": [1, 2], + "os_version": "14.1", + "build_version": "23B74", + "local_datetime": "2023-11-05T09:30:00", + "max_os_version": "", + "delay_days": null, + "local_time": null, + "rotate_firmware_password": true, + "created_at": "2022-07-22T01:02:03.444444", + "updated_at": "2022-07-22T01:02:03.444444" + } +] +` + +var msueGetJSONResponse = ` +{ + "id": 4, + "name": "Default", + "details_url": "https://www.example.com", + "tags": [], + "os_version": "", + "build_version": "", + "local_datetime": null, + "max_os_version": "15", + "delay_days": 7, + "local_time": "09:30:00", + "created_at": "2022-07-22T01:02:03.444444", + "updated_at": "2022-07-22T01:02:03.444444" +} +` + +var msueCreateJSONResponse = ` +{ + "id": 4, + "name": "Default", + "details_url": "https://www.example.com", + "tags": [1, 2], + "os_version": "", + "build_version": "", + "local_datetime": null, + "max_os_version": "15", + "delay_days": 7, + "local_time": "09:30:00", + "created_at": "2022-07-22T01:02:03.444444", + "updated_at": "2022-07-22T01:02:03.444444" +} +` + +var msueUpdateJSONResponse = ` +{ + "id": 4, + "name": "Default", + "details_url": "https://www.example.com", + "tags": [1, 2], + "os_version": "", + "build_version": "", + "local_datetime": null, + "max_os_version": "15", + "delay_days": 7, + "local_time": "09:30:00", + "created_at": "2022-07-22T01:02:03.444444", + "updated_at": "2022-07-22T01:02:03.444444" +} +` + +func TestMDMSoftwareUpdateEnforcementsService_List(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/mdm/software_update_enforcements/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", "application/json") + fmt.Fprint(w, msueListJSONResponse) + }) + + ctx := context.Background() + got, _, err := client.MDMSoftwareUpdateEnforcements.List(ctx, nil) + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.List returned error: %v", err) + } + + want := []MDMSoftwareUpdateEnforcement{ + { + ID: 4, + Name: "Default", + DetailsURL: "https://www.example.com", + TagIDs: []int{1, 2}, + OSVersion: "14.1", + BuildVersion: "23B74", + LocalDateTime: String("2023-11-05T09:30:00"), + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, + }, + } + if !cmp.Equal(got, want) { + t.Errorf("MDMSoftwareUpdateEnforcements.List returned %+v, want %+v", got, want) + } +} + +func TestMDMSoftwareUpdateEnforcementsService_GetByID(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/mdm/software_update_enforcements/4/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", "application/json") + fmt.Fprint(w, msueGetJSONResponse) + }) + + ctx := context.Background() + got, _, err := client.MDMSoftwareUpdateEnforcements.GetByID(ctx, 4) + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.GetByID returned error: %v", err) + } + + want := &MDMSoftwareUpdateEnforcement{ + ID: 4, + Name: "Default", + DetailsURL: "https://www.example.com", + TagIDs: []int{}, + MaxOSVersion: "15", + DelayDays: Int(7), + LocalTime: String("09:30:00"), + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, + } + if !cmp.Equal(got, want) { + t.Errorf("MDMSoftwareUpdateEnforcements.GetByID returned %+v, want %+v", got, want) + } +} + +func TestMDMSoftwareUpdateEnforcementsService_GetByName(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/mdm/software_update_enforcements/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", "application/json") + testQueryArg(t, r, "name", "Default") + fmt.Fprint(w, msueListJSONResponse) + }) + + ctx := context.Background() + got, _, err := client.MDMSoftwareUpdateEnforcements.GetByName(ctx, "Default") + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.GetByName returned error: %v", err) + } + + want := &MDMSoftwareUpdateEnforcement{ + ID: 4, + Name: "Default", + DetailsURL: "https://www.example.com", + TagIDs: []int{1, 2}, + OSVersion: "14.1", + BuildVersion: "23B74", + LocalDateTime: String("2023-11-05T09:30:00"), + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, + } + if !cmp.Equal(got, want) { + t.Errorf("MDMSoftwareUpdateEnforcements.GetByName returned %+v, want %+v", got, want) + } +} + +func TestMDMSoftwareUpdateEnforcementsService_Create(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + createRequest := &MDMSoftwareUpdateEnforcementRequest{ + Name: "Default", + DetailsURL: "https://www.example.com", + TagIDs: []int{1, 2}, + MaxOSVersion: "15", + DelayDays: Int(7), + LocalTime: String("09:30:00"), + } + + mux.HandleFunc("/mdm/software_update_enforcements/", func(w http.ResponseWriter, r *http.Request) { + v := new(MDMSoftwareUpdateEnforcementRequest) + err := json.NewDecoder(r.Body).Decode(v) + if err != nil { + t.Fatal(err) + } + testMethod(t, r, "POST") + testHeader(t, r, "Accept", "application/json") + testHeader(t, r, "Content-Type", "application/json") + assert.Equal(t, createRequest, v) + + fmt.Fprint(w, msueCreateJSONResponse) + }) + + ctx := context.Background() + got, _, err := client.MDMSoftwareUpdateEnforcements.Create(ctx, createRequest) + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.Create returned error: %v", err) + } + + want := &MDMSoftwareUpdateEnforcement{ + ID: 4, + Name: "Default", + TagIDs: []int{1, 2}, + DetailsURL: "https://www.example.com", + MaxOSVersion: "15", + DelayDays: Int(7), + LocalTime: String("09:30:00"), + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, + } + if !cmp.Equal(got, want) { + t.Errorf("MDMSoftwareUpdateEnforcements.Create returned %+v, want %+v", got, want) + } +} + +func TestMDMSoftwareUpdateEnforcementsService_Update(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + updateRequest := &MDMSoftwareUpdateEnforcementRequest{ + Name: "Default", + TagIDs: []int{1, 2}, + DetailsURL: "https://www.example.com", + MaxOSVersion: "15", + DelayDays: Int(7), + LocalTime: String("09:30:00"), + } + + mux.HandleFunc("/mdm/software_update_enforcements/4/", func(w http.ResponseWriter, r *http.Request) { + v := new(MDMSoftwareUpdateEnforcementRequest) + err := json.NewDecoder(r.Body).Decode(v) + if err != nil { + t.Fatal(err) + } + testMethod(t, r, "PUT") + testHeader(t, r, "Accept", "application/json") + testHeader(t, r, "Content-Type", "application/json") + assert.Equal(t, updateRequest, v) + fmt.Fprint(w, msueUpdateJSONResponse) + }) + + ctx := context.Background() + got, _, err := client.MDMSoftwareUpdateEnforcements.Update(ctx, 4, updateRequest) + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.Update returned error: %v", err) + } + + want := &MDMSoftwareUpdateEnforcement{ + ID: 4, + Name: "Default", + TagIDs: []int{1, 2}, + DetailsURL: "https://www.example.com", + MaxOSVersion: "15", + DelayDays: Int(7), + LocalTime: String("09:30:00"), + Created: Timestamp{referenceTime}, + Updated: Timestamp{referenceTime}, + } + if !cmp.Equal(got, want) { + t.Errorf("MDMSoftwareUpdateEnforcements.Update returned %+v, want %+v", got, want) + } +} + +func TestMDMSoftwareUpdateEnforcementsService_Delete(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/mdm/software_update_enforcements/4/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + w.WriteHeader(http.StatusNoContent) + }) + + ctx := context.Background() + _, err := client.MDMSoftwareUpdateEnforcements.Delete(ctx, 4) + if err != nil { + t.Errorf("MDMSoftwareUpdateEnforcements.Delete returned error: %v", err) + } +}