Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit

Permalink
Add HubSites
Browse files Browse the repository at this point in the history
pschaeflein committed Nov 20, 2023

Unverified

The email in this signature doesn’t match the committer email.
1 parent 7fd5b6a commit 10572a4
Showing 13 changed files with 308 additions and 1 deletion.
7 changes: 6 additions & 1 deletion docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -124,5 +124,10 @@ Interested in [SharePoint User Profile REST reference](https://docs.microsoft.co

### Hub Sites

Interested in [Hub Sites REST API](https://docs.microsoft.com/en-us/sharepoint/dev/features/hub-site/hub-site-rest-api)? [Open an issue](https://github.com/microsoftgraph/msgraph-sdk-dotnet-contrib/issues/new)
The following operations allow for retrieving HubSites.

| Operation | Request Builder | Method | Released version |
|------------------|-----------------|--------------------------|------------------|
| GetHubSites | `.Hubs` | GetAsync | 4.54.5 |


47 changes: 47 additions & 0 deletions src/Models/Hub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace Graph.Community
{
public class Hub
{
/// <summary>
/// Identifies the hub site.
/// </summary>
public string Id { get; set; }

/// <summary>
/// The display name of the hub site.
/// </summary>
public string Title { get; set; }

/// <summary>
/// ID of the hub parent site.
/// </summary>
public string SiteId { get; set; }

/// <summary>
/// The tenant instance ID in which the hub site is located. Use empty GUID for the default tenant instance.
/// </summary>
public string TenantInstanceId { get; set; }

/// <summary>
/// URL of the hub parent site.
/// </summary>
public string SiteUrl { get; set; }

/// <summary>
/// The URL of a logo to use in the hub site navigation.
/// </summary>
public string LogoUrl { get; set; }

/// <summary>
/// A description of the hub site.
/// </summary>
public string Description { get; set; }

/// <summary>
/// List of security groups with access to join the hub site. Null if everyone has permission.
/// </summary>
public string Targets { get; set; }

public bool RequiresJoinApproval { get; set; }
}
}
8 changes: 8 additions & 0 deletions src/Requests/Hubs/HubCollectionPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Microsoft.Graph;

namespace Graph.Community
{
public class HubCollectionPage: CollectionPage<Hub>, IHubCollectionPage
{
}
}
38 changes: 38 additions & 0 deletions src/Requests/Hubs/HubCollectionRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Graph;

namespace Graph.Community
{
public class HubCollectionRequest:BaseSharePointAPIRequest, IHubCollectionRequest
{
public HubCollectionRequest(
string requestUrl,
IBaseClient client,
IEnumerable<Option> options)
: base("SitePages", requestUrl, client, options)
{
this.Headers.Add(new HeaderOption(SharePointAPIRequestConstants.Headers.AcceptHeaderName, SharePointAPIRequestConstants.Headers.AcceptHeaderValue));
this.Headers.Add(new HeaderOption(SharePointAPIRequestConstants.Headers.ODataVersionHeaderName, SharePointAPIRequestConstants.Headers.ODataVersionHeaderValue));
}

public Task<IHubCollectionPage> GetAsync()
{
return this.GetAsync(CancellationToken.None);
}

public async Task<IHubCollectionPage> GetAsync(CancellationToken cancellationToken)
{
this.ContentType = "application/json";
var response = await this.SendAsync<SharePointAPICollectionResponse<IHubCollectionPage>>(null, cancellationToken).ConfigureAwait(false);

if (response?.Value?.CurrentPage != null)
{
return response.Value;
}

return null;
}
}
}
31 changes: 31 additions & 0 deletions src/Requests/Hubs/HubCollectionRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Graph;

namespace Graph.Community
{
public class HubCollectionRequestBuilder : BaseRequestBuilder, IHubCollectionRequestBuilder
{
private readonly IEnumerable<Option> options;

public HubCollectionRequestBuilder(
string requestUrl,
IBaseClient client,
IEnumerable<Option> options = null)
: base(requestUrl, client)
{
this.options = options;
}

public IHubCollectionRequest Request()
{
return this.Request(options);
}

public IHubCollectionRequest Request(IEnumerable<Option> options)
{
return new HubCollectionRequest(this.AppendSegmentToRequestUrl("HubSites"), this.Client, options);
}
}
}
9 changes: 9 additions & 0 deletions src/Requests/Hubs/IHubCollectionPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.Graph;

namespace Graph.Community
{
[InterfaceConverter(typeof(InterfaceConverter<HubCollectionPage>))]
public interface IHubCollectionPage:ICollectionPage<Hub>
{
}
}
12 changes: 12 additions & 0 deletions src/Requests/Hubs/IHubCollectionRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Graph;

namespace Graph.Community
{
public interface IHubCollectionRequest:IBaseRequest
{
Task<IHubCollectionPage> GetAsync();
Task<IHubCollectionPage> GetAsync(CancellationToken cancellationToken);
}
}
12 changes: 12 additions & 0 deletions src/Requests/Hubs/IHubCollectionRequestBuilder .cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using Microsoft.Graph;

namespace Graph.Community
{
public interface IHubCollectionRequestBuilder:IBaseRequestBuilder
{
IHubCollectionRequest Request();

IHubCollectionRequest Request(IEnumerable<Option> options);
}
}
2 changes: 2 additions & 0 deletions src/Requests/ISharePointAPIRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -19,5 +19,7 @@ public interface ISharePointAPIRequestBuilder : IBaseRequestBuilder
ISearchRequestBuilder Search { get; }

ITenantRequestBuilder Tenant { get; }

IHubCollectionRequestBuilder Hubs { get; }
}
}
8 changes: 8 additions & 0 deletions src/Requests/SharePointAPIRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -74,5 +74,13 @@ public Graph.Community.ITenantRequestBuilder Tenant
return new Graph.Community.TenantRequestBuilder(this.AppendSegmentToRequestUrl("_api"), this.Client);
}
}

public IHubCollectionRequestBuilder Hubs
{
get
{
return new Graph.Community.HubCollectionRequestBuilder(this.AppendSegmentToRequestUrl("_api"), this.Client);
}
}
}
}
2 changes: 2 additions & 0 deletions test/Graph.Community.Test.csproj
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
</PropertyGroup>

<ItemGroup>
<None Remove="Mocks\GetHubsResponse.json" />
<None Remove="Mocks\GetSiteResponse.json" />
</ItemGroup>

@@ -16,6 +17,7 @@
<EmbeddedResource Include="Mocks\CreateSiteScriptResponse.json" />
<EmbeddedResource Include="Mocks\EnsureUserResponse.json" />
<EmbeddedResource Include="Mocks\GetChangesResponse.json" />
<EmbeddedResource Include="Mocks\GetHubsResponse.json" />
<EmbeddedResource Include="Mocks\GetListFieldsResponse.json" />
<EmbeddedResource Include="Mocks\GetListItemResponse.json" />
<EmbeddedResource Include="Mocks\GetListItemsResponse.json" />
98 changes: 98 additions & 0 deletions test/HubCollectionRequestTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace Graph.Community.Test
{
public class HubCollectionRequestTests
{
private readonly ITestOutputHelper output;

private readonly string mockWebUrl = "https://mock.sharepoint.com/sites/mockSite";

public HubCollectionRequestTests(ITestOutputHelper output)
{
this.output = output;
}

[Fact]
public void Get_GeneratesCorrectRequest()
{
// ARRANGE
var mockListId = Guid.NewGuid();
var expectedUri = new Uri($"{mockWebUrl}/_api/HubSites");

using HttpResponseMessage response = new HttpResponseMessage();
using TestGraphServiceClient testClient = TestGraphServiceClient.Create(response);

// ACT
var request = testClient.GraphServiceClient
.SharePointAPI(mockWebUrl)
.Hubs
.Request()
.GetAsync();

// ASSERT
testClient.HttpProvider.Verify(
provider => provider.SendAsync(
It.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Get &&
req.RequestUri == expectedUri
),
It.IsAny<HttpCompletionOption>(),
It.IsAny<CancellationToken>()
),
Times.Exactly(1)
);
}

[Fact]
public async Task Get_ReturnsCorrectResponse()
{
// ARRANGE
var responseContent = ResourceManager.GetHttpResponseContent("GetHubsResponse.json");
var responseMessage = new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(responseContent),
};

using (responseMessage)
using (var gsc = TestGraphServiceClient.Create(responseMessage))
{
// ACT
var response = await gsc.GraphServiceClient
.SharePointAPI(mockWebUrl)
.Hubs
.Request()
.GetAsync();
var actual = response.CurrentPage;

// ASSERT
Assert.IsAssignableFrom<IList<Hub>>(actual);
Assert.Equal(2, actual.Count);

var testHub = actual[1];
Assert.IsType<Graph.Community.Hub>(testHub);
Assert.Equal("d8ab01e9-1634-44dd-91fe-1e6ff8385c34", testHub.Id);
Assert.Equal("Contoso Department Hub", testHub.Title);
Assert.Null(testHub.Description);
Assert.Equal("https://contoso.sharepoint.com/sites/ContosoDepartment/SiteAssets/__sitelogo__keep_calm_hit_refresh.png", testHub.LogoUrl);
Assert.Equal("https://contoso.sharepoint.com/sites/ContosoDepartment", testHub.SiteUrl);
Assert.Equal("82e8cb67-c4f1-4b38-80aa-0342294f5ece", testHub.SiteId);
Assert.Null(testHub.Targets);
Assert.Equal(Guid.Empty.ToString(), testHub.TenantInstanceId);
Assert.True(testHub.RequiresJoinApproval);
}
}

}
}
35 changes: 35 additions & 0 deletions test/Mocks/GetHubsResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"@odata.context": "https://contoso.sharepoint.com/_api/$metadata#hubsites",
"value": [
{
"@odata.type": "#SP.HubSite",
"@odata.id": "https://contoso.sharepoint.com/_api/SP.HubSite9dbd0488-5d8d-4ce6-941e-e5650bc216f4",
"@odata.etag": "\"2\"",
"@odata.editLink": "SP.HubSite9dbd0488-5d8d-4ce6-941e-e5650bc216f4",
"Description": null,
"ID": "82e8cb67-c4f1-4b38-80aa-0342294f5ece",
"LogoUrl": "https://contoso.sharepoint.com/sites/ContosoTravelMarketing/SiteAssets/__hubLogo____hubLogo__.png",
"SiteId": "82e8cb67-c4f1-4b38-80aa-0342294f5ece",
"SiteUrl": "https://contoso.sharepoint.com/sites/ContosoTravelMarketing",
"RequiresJoinApproval": false,
"Targets": null,
"TenantInstanceId": "00000000-0000-0000-0000-000000000000",
"Title": "Contoso Travel Marketing"
},
{
"@odata.type": "#SP.HubSite",
"@odata.id": "https://contoso.sharepoint.com/_api/SP.HubSitee3e23fc3-870c-4de1-89c0-85b378e42b2e",
"@odata.etag": "\"1\"",
"@odata.editLink": "SP.HubSitee3e23fc3-870c-4de1-89c0-85b378e42b2e",
"Description": null,
"ID": "d8ab01e9-1634-44dd-91fe-1e6ff8385c34",
"LogoUrl": "https://contoso.sharepoint.com/sites/ContosoDepartment/SiteAssets/__sitelogo__keep_calm_hit_refresh.png",
"RequiresJoinApproval": true,
"SiteId": "82e8cb67-c4f1-4b38-80aa-0342294f5ece",
"SiteUrl": "https://contoso.sharepoint.com/sites/ContosoDepartment",
"Targets": null,
"TenantInstanceId": "00000000-0000-0000-0000-000000000000",
"Title": "Contoso Department Hub"
}
]
}

0 comments on commit 10572a4

Please sign in to comment.