Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#255 add collections to spaces #256

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"collection": {
"id": "df334bbb-6540-41cc-9aad-ea7114fb47ee"
},
"spaces": [
{ "id": "ece703a9-900e-4781-9d21-bdfbf9762751" },
{ "id": "f87dadc0-a0ac-4d3f-bdfd-6dc1df575ab5" }
],
"sitemap_locations": [],
"last_modified": "2021-05-28T11:54:49.8609984Z"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"collection": {
"id": "df334bbb-6540-41cc-9aad-ea7114fb47ee"
},
"spaces": [
{ "id": "ece703a9-900e-4781-9d21-bdfbf9762751" },
{ "id": "f87dadc0-a0ac-4d3f-bdfd-6dc1df575ab5" }
],
"sitemap_locations": [],
"last_modified": "2021-05-28T11:54:49.8609984Z"
},
Expand All @@ -23,6 +27,7 @@
"collection": {
"id": "00000000-0000-0000-0000-000000000000"
},
"spaces": [],
"sitemap_locations": [],
"last_modified": "2021-01-06T07:23:56.0307608Z"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"collection": {
"id": "00000000-0000-0000-0000-000000000000"
},
"spaces": [],
"sitemap_locations": [],
"last_modified": "2021-02-16T12:25:20.1269357Z"
},
Expand All @@ -23,6 +24,7 @@
"collection": {
"id": "00000000-0000-0000-0000-000000000000"
},
"spaces": [],
"sitemap_locations": [],
"last_modified": "2021-07-07T10:00:39.9575259Z"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"collection": {
"id": "df334bbb-6540-41cc-9aad-ea7114fb47ee"
},
"spaces": [
{ "id": "ece703a9-900e-4781-9d21-bdfbf9762751" },
{ "id": "f87dadc0-a0ac-4d3f-bdfd-6dc1df575ab5" }
],
"sitemap_locations": [],
"last_modified": "2021-05-28T12:08:35.9298382Z"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"name": "New space name",
"web_spotlight_root_item": {
"id": "1024356f-858f-421a-b804-07c6bfe10ce5"
}
},
"collections": [
{ "id": "b38269bf-873c-4021-99ee-e63c7850a505" },
{ "id": "d884b892-4aef-4cd0-8910-68887f69d280" }
]
}
6 changes: 5 additions & 1 deletion Kontent.Ai.Management.Tests/Data/Space/Space.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"name": "Space 1",
"web_spotlight_root_item": {
"id": "1024356f-858f-421a-b804-07c6bfe10ce5"
}
},
"collections": [
{ "id": "cfa0dbac-436f-4e15-865b-6a1795523e80" },
{ "id": "d884b892-4aef-4cd0-8910-68887f69d280" }
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,44 @@ await client.Invoking(x => x.ListLanguageVariantsByCollectionAsync(null))
.Should().ThrowExactlyAsync<ArgumentNullException>();
}


[Fact]
public async void ListLanguageVariantsBySpaceAsync_DynamicallyTyped_ListsVariants()
{
var client = _scenario
.WithResponses("LanguageVariantsPage1.json", "LanguageVariantsPage2.json", "LanguageVariantsPage3.json")
.CreateManagementClient();

var expected = new[]
{
(itemId: "00000000-0000-0000-0000-000000000000", languageId: "00000000-0000-0000-0000-000000000000"),
(itemId: "00000000-0000-0000-0000-000000000000", languageId: "10000000-0000-0000-0000-000000000000"),
(itemId: "10000000-0000-0000-0000-000000000000", languageId: "00000000-0000-0000-0000-000000000000"),
(itemId: "10000000-0000-0000-0000-000000000000", languageId: "10000000-0000-0000-0000-000000000000"),
(itemId: "20000000-0000-0000-0000-000000000000", languageId: "00000000-0000-0000-0000-000000000000"),
(itemId: "20000000-0000-0000-0000-000000000000", languageId: "10000000-0000-0000-0000-000000000000")
}.Select(x => GetExpectedLanguageVariantModel(x.languageId, x.itemId));

var identifier = Reference.ById(Guid.Parse("f81647c8-778a-4b20-a47e-d09dc8541151"));
var response = await client.ListLanguageVariantsBySpaceAsync(identifier).GetAllAsync();

_scenario
.CreateExpectations()
.HttpMethod(HttpMethod.Get)
.Response(response, expected)
.Url($"{Endpoint}/projects/{PROJECT_ID}/spaces/{identifier.Id}/variants")
.Validate();
}

[Fact]
public async Task ListLanguageVariantsBySpaceAsync_DynamicallyTyped_IdentifierIsNull_Throws()
{
var client = _scenario.CreateManagementClient();

await client.Invoking(x => x.ListLanguageVariantsBySpaceAsync(null))
.Should().ThrowExactlyAsync<ArgumentNullException>();
}

[Theory]
[ClassData(typeof(CombinationOfIdentifiersAndUrl))]
public async Task GetLanguageVariantAsync_StronglyTyped_GetsVariant(LanguageVariantIdentifier identifier, string expectedUrl)
Expand Down
156 changes: 114 additions & 42 deletions Kontent.Ai.Management.Tests/ManagementClientTests/SpaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,109 +4,181 @@
using Kontent.Ai.Management.Models.Spaces.Patch;
using Kontent.Ai.Management.Tests.Base;
using System;
using System.Collections.Generic;
using System.Net.Http;
using Xunit;
using static Kontent.Ai.Management.Tests.Base.Scenario;

namespace Kontent.Ai.Management.Tests.ManagementClientTests;

public class SpaceTests : IClassFixture<FileSystemFixture>
{
private readonly FileSystemFixture _fileSystemFixture;

public SpaceTests(FileSystemFixture fileSystemFixture)
{
_fileSystemFixture = fileSystemFixture;
_fileSystemFixture.SetSubFolder("Space");
}
private static readonly string SpacesBaseUrl = $"{Endpoint}/projects/{PROJECT_ID}/spaces";
private readonly Scenario _scenario = new("Space");

[Fact]
public async void CreateSpace_CreatesSpace()
{
var client = _fileSystemFixture.CreateMockClientWithResponse("Space.json");
var client = _scenario.WithResponses("Space.json").CreateManagementClient();
var expected = _scenario.GetExpectedResponse<SpaceModel>();
var createModel = new SpaceCreateModel {
Codename = expected.Codename,
Name = expected.Name,
WebSpotlightRootItem = expected.WebSpotlightRootItem,
Collections = expected.Collections
};

var expected = _fileSystemFixture.GetExpectedResponse<SpaceModel>("Space.json");
var response = await client.CreateSpaceAsync(createModel);

var createModel = new SpaceCreateModel { Codename = expected.Codename, Name = expected.Name, WebSpotlightRootItem = expected.WebSpotlightRootItem };
_scenario.CreateExpectations()
.HttpMethod(HttpMethod.Post)
.RequestPayload(createModel)
.Response(response)
.Url(SpacesBaseUrl)
.Validate();
}

var response = await client.CreateSpaceAsync(createModel);
[Fact]
public async void CreateSpace_ModelIsNull_Throws()
{
var client = _scenario.CreateManagementClient();

response.Should().BeEquivalentTo(expected);
await client.Invoking(x => x.CreateSpaceAsync(null)).Should().ThrowAsync<ArgumentNullException>();
}

[Fact]
public async void ListSpaces_ListsSpaces()
{
var client = _fileSystemFixture.CreateMockClientWithResponse("Spaces.json");

var expected = _fileSystemFixture.GetExpectedResponse<IEnumerable<SpaceModel>>("Spaces.json");
var client = _scenario.WithResponses("Spaces.json").CreateManagementClient();

var response = await client.ListSpacesAsync();

response.Should().BeEquivalentTo(expected);
_scenario.CreateExpectations()
.HttpMethod(HttpMethod.Get)
.Response(response)
.Url(SpacesBaseUrl)
.Validate();
}

[Fact]
public async void GetSpace_ById_GetsSpace()
{
var client = _fileSystemFixture.CreateMockClientWithResponse("Space.json");
var client = _scenario.WithResponses("Space.json").CreateManagementClient();
var identifier = Reference.ById(Guid.NewGuid());

var expected = _fileSystemFixture.GetExpectedResponse<SpaceModel>("Space.json");
var response = await client.GetSpaceAsync(identifier);

var response = await client.GetSpaceAsync(Reference.ById(expected.Id));

response.Should().BeEquivalentTo(expected);
_scenario.CreateExpectations()
.HttpMethod(HttpMethod.Get)
.Response(response)
.Url(SpacesBaseUrl + $"/{identifier.Id}")
.Validate();
}

[Fact]
public async void GetSpace_ByCodename_GetsSpace()
{
var client = _fileSystemFixture.CreateMockClientWithResponse("Space.json");

var expected = _fileSystemFixture.GetExpectedResponse<SpaceModel>("Space.json");
var client = _scenario.WithResponses("Space.json").CreateManagementClient();
var identifier = Reference.ByCodename("space_1");

var response = await client.GetSpaceAsync(Reference.ByCodename(expected.Codename));
var response = await client.GetSpaceAsync(identifier);

response.Should().BeEquivalentTo(expected);
_scenario.CreateExpectations()
.HttpMethod(HttpMethod.Get)
.Response(response)
.Url(SpacesBaseUrl + $"/codename/{identifier.Codename}")
.Validate();
}

[Fact]
public async void ModifySpace_Replace_ModifiesSpace()
public async void GetSpace_IdentifierIsNull_Throws()
{
var client = _fileSystemFixture.CreateMockClientWithResponse("ModifySpace_Replace_ModifiesSpace.json");
var client = _scenario.CreateManagementClient();

var expected = _fileSystemFixture.GetExpectedResponse<SpaceModel>("ModifySpace_Replace_ModifiesSpace.json");
await client.Invoking(x => x.GetSpaceAsync(null)).Should().ThrowAsync<ArgumentNullException>();
}

[Fact]
public async void ModifySpace_Replace_ModifiesSpace()
{
var client = _scenario.WithResponses("ModifySpace_Replace_ModifiesSpace.json").CreateManagementClient();
var identifier = Reference.ById(Guid.NewGuid());
var changes = new SpaceOperationReplaceModel[]
{
new() { PropertyName = PropertyName.Name, Value = "New space name" },
new() { PropertyName = PropertyName.Codename, Value = "new_space_codename" },
new() { PropertyName = PropertyName.WebSpotlightRootItem, Value = Reference.ById(Guid.Parse("1024356f-858f-421a-b804-07c6bfe10ce5")) }

new() { PropertyName = PropertyName.WebSpotlightRootItem, Value = identifier },
new() { PropertyName = PropertyName.Collections, Value = new[] {
Reference.ByCodename("collection_codename"),
Reference.ById(Guid.NewGuid()) }
}
};

var response = await client.ModifySpaceAsync(Reference.ById(expected.Id), changes);
var response = await client.ModifySpaceAsync(identifier, changes);

response.Should().BeEquivalentTo(expected);
_scenario.CreateExpectations()
.HttpMethod(HttpMethod.Patch)
.RequestPayload(changes)
.Response(response)
.Url(SpacesBaseUrl + $"/{identifier.Id}")
.Validate();
}

[Fact]
public async void ModifySpace_IdentifierIsNull_Throws()
{
var client = _scenario.CreateManagementClient();
var changes = new SpaceOperationReplaceModel[]
{
new() { PropertyName = PropertyName.Name, Value = "New space name" }
};

await client.Invoking(x => x.ModifySpaceAsync(null, changes)).Should().ThrowAsync<ArgumentNullException>();
}

[Fact]
public async void ModifySpace_ChangesAreNull_Throws()
{
var client = _scenario.CreateManagementClient();
var identifier = Reference.ById(Guid.NewGuid());

await client.Invoking(x => x.ModifySpaceAsync(identifier, null)).Should().ThrowAsync<ArgumentNullException>();
}

[Fact]
public async void DeleteSpace_ById_DeletesSpace()
{
var client = _fileSystemFixture.CreateMockClientWithoutResponse();

var deleteSpace = async () => await client.DeleteSpaceAsync(Reference.ById(Guid.NewGuid()));
var client = _scenario.CreateManagementClient();
var identifier = Reference.ById(Guid.NewGuid());

await client.DeleteSpaceAsync(identifier);

await deleteSpace.Should().NotThrowAsync();
_scenario
.CreateExpectations()
.Url(SpacesBaseUrl + $"/{identifier.Id}")
.HttpMethod(HttpMethod.Delete)
.Validate();
}

[Fact]
public async void DeleteSpace_ByCodename_DeletesSpace()
{
var client = _fileSystemFixture.CreateMockClientWithoutResponse();

var deleteSpace = async () => await client.DeleteSpaceAsync(Reference.ByCodename("space_1"));
var client = _scenario.CreateManagementClient();
var identifier = Reference.ByCodename("space_1");

await client.DeleteSpaceAsync(identifier);

_scenario.CreateExpectations()
.Url(SpacesBaseUrl + $"/codename/{identifier.Codename}")
.HttpMethod(HttpMethod.Delete)
.Validate();
}

[Fact]
public async void DeleteSpace_IdentifierIsNull_Throws()
{
var client = _scenario.CreateManagementClient();

await deleteSpace.Should().NotThrowAsync();
await client.Invoking(x => x.DeleteSpaceAsync(null)).Should().ThrowAsync<ArgumentNullException>();
}
}

10 changes: 10 additions & 0 deletions Kontent.Ai.Management/IManagementClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,16 @@ public interface IManagementClient
/// <returns>The <see cref="IEnumerable{LanguageVariantModel}"/> instance that represents the listing of language variants.</returns>
Task<IListingResponseModel<LanguageVariantModel>> ListLanguageVariantsByCollectionAsync(Reference identifier);

/// <summary>
/// Returns strongly typed listing of language variants for specified space.
/// The Content management API returns a dynamically paginated listing response limited to up to 100 objects.
/// To check if the next page is available use <see cref="IListingResponseModel{T}.HasNextPage"/>.
/// For getting next page use <see cref="IListingResponseModel{T}.GetNextPage"/>.
/// </summary>
/// <param name="identifier">The identifier of the collection.</param>
/// <returns>The <see cref="IEnumerable{LanguageVariantModel}"/> instance that represents the listing of language variants.</returns>
Task<IListingResponseModel<LanguageVariantModel>> ListLanguageVariantsBySpaceAsync(Reference identifier);

/// <summary>
/// Returns strongly typed listing of language variants for the specified content item.
/// </summary>
Expand Down
15 changes: 15 additions & 0 deletions Kontent.Ai.Management/ManagementClient.LanguageVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ public async Task<IListingResponseModel<LanguageVariantModel>> ListLanguageVaria
response.Variants);
}

/// <inheritdoc />
public async Task<IListingResponseModel<LanguageVariantModel>> ListLanguageVariantsBySpaceAsync(Reference identifier)
{
ArgumentNullException.ThrowIfNull(identifier);

var endpointUrl = _urlBuilder.BuildListVariantsBySpaceUrl(identifier);
var response = await _actionInvoker.InvokeReadOnlyMethodAsync<LanguageVariantsListingResponseServerModel>(endpointUrl, HttpMethod.Get);

return new ListingResponseModel<LanguageVariantModel>(
(token, url) => GetNextListingPageAsync<LanguageVariantsListingResponseServerModel, LanguageVariantModel>(token, url),
response.Pagination?.Token,
endpointUrl,
response.Variants);
}

/// <inheritdoc />
public async Task<List<LanguageVariantModel<T>>> ListLanguageVariantsByItemAsync<T>(Reference identifier) where T : new()
{
Expand Down
Loading
Loading