From 2cb127943d185b6b04bc5a569b3d67fb5c1bcb77 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 17 Jul 2026 08:51:23 +0100 Subject: [PATCH] onedrive: skip permission tests when the server refuses sharing invitations Microsoft has been progressively disabling sharing invitations on both Business and Personal accounts - the driveItem invite API returns 400 sharingFailed for any recipient on affected accounts - which makes the permission writing tests impossible. Probe the API once and skip the tests which need it when it is refused. --- backend/onedrive/onedrive_internal_test.go | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/backend/onedrive/onedrive_internal_test.go b/backend/onedrive/onedrive_internal_test.go index 6ce22bc8f..01ed7d3eb 100644 --- a/backend/onedrive/onedrive_internal_test.go +++ b/backend/onedrive/onedrive_internal_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "slices" + "strings" "testing" "time" @@ -41,8 +42,39 @@ func TestMain(m *testing.M) { fstest.TestMain(m) } +// sharingRefused caches whether the remote refuses sharing invitations. +var sharingRefused *bool + +// skipIfSharingRefused skips t if the remote cannot add permissions via +// the driveItem invite API. +// +// Microsoft has been progressively disabling sharing invitations on +// both Business and Personal accounts (the invite API returns 400 +// sharingFailed for any recipient on affected accounts), which makes +// the permission writing tests impossible. +func (f *Fs) skipIfSharingRefused(t *testing.T, r *fstest.Run) { + if sharingRefused == nil { + file := r.WriteObject(ctx, randomFilename(), "sharing probe", t2) + obj, err := r.Fremote.NewObject(ctx, file.Path) + require.NoError(t, err) + m := f.newMetadata(obj.Remote()) + m.normalizedID = obj.(*Object).id + p := defaultPermissions(f.driveType)[0] + p.Roles[0] = api.ReadRole + _, _, err = m.addPermission(ctx, p) + _ = obj.Remove(ctx) + refused := err != nil && strings.Contains(err.Error(), "sharingFailed") + sharingRefused = &refused + } + if *sharingRefused { + t.Skip("skipping test: server refuses sharing invitations (sharingFailed)") + } +} + // TestWritePermissions tests reading and writing permissions func (f *Fs) TestWritePermissions(t *testing.T, r *fstest.Run) { + f.skipIfSharingRefused(t, r) + // setup ctx, ci := fs.AddConfig(ctx) ci.Metadata = true @@ -141,6 +173,8 @@ func (f *Fs) TestReadPermissions(t *testing.T, r *fstest.Run) { // TestReadMetadata tests that all the read-only system properties are present and non-blank func (f *Fs) TestReadMetadata(t *testing.T, r *fstest.Run) { + f.skipIfSharingRefused(t, r) + // setup ctx, ci := fs.AddConfig(ctx) ci.Metadata = true @@ -165,6 +199,8 @@ func (f *Fs) TestReadMetadata(t *testing.T, r *fstest.Run) { // TestDirectoryMetadata tests reading and writing modtime and other metadata and permissions for directories func (f *Fs) TestDirectoryMetadata(t *testing.T, r *fstest.Run) { + f.skipIfSharingRefused(t, r) + // setup ctx, ci := fs.AddConfig(ctx) ci.Metadata = true @@ -276,6 +312,8 @@ func (f *Fs) TestDirectoryMetadata(t *testing.T, r *fstest.Run) { // TestServerSideCopyMove tests server-side Copy and Move func (f *Fs) TestServerSideCopyMove(t *testing.T, r *fstest.Run) { + f.skipIfSharingRefused(t, r) + // setup ctx, ci := fs.AddConfig(ctx) ci.Metadata = true @@ -320,6 +358,8 @@ func (f *Fs) TestServerSideCopyMove(t *testing.T, r *fstest.Run) { // TestMetadataMapper tests adding permissions with the --metadata-mapper func (f *Fs) TestMetadataMapper(t *testing.T, r *fstest.Run) { + f.skipIfSharingRefused(t, r) + // setup ctx, ci := fs.AddConfig(ctx) ci.Metadata = true