Browse Source

Add a test for content version endpoint. (#807)

* Add a test for content version endpoint.

* Refactor tests into smaller chunks.

* Fix tests.

* Own app for clients tests.
pull/811/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
50d8766ab9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      backend/src/Squidex.Web/Resources.cs
  2. 119
      backend/tools/TestSuite/TestSuite.ApiTests/AppClientsTests.cs
  3. 97
      backend/tools/TestSuite/TestSuite.ApiTests/AppContributorsTests.cs
  4. 175
      backend/tools/TestSuite/TestSuite.ApiTests/AppLanguagesTests.cs
  5. 175
      backend/tools/TestSuite/TestSuite.ApiTests/AppRolesTests.cs
  6. 283
      backend/tools/TestSuite/TestSuite.ApiTests/AppTests.cs
  7. 121
      backend/tools/TestSuite/TestSuite.ApiTests/AppWorkflowsTest.cs
  8. 2
      backend/tools/TestSuite/TestSuite.ApiTests/ContentCleanupTests.cs
  9. 41
      backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs
  10. 1
      backend/tools/TestSuite/TestSuite.ApiTests/SchemaTests.cs
  11. 2
      backend/tools/TestSuite/TestSuite.ApiTests/Setup.cs
  12. 4
      backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj
  13. 4
      backend/tools/TestSuite/TestSuite.LoadTests/TestSuite.LoadTests.csproj
  14. 2
      backend/tools/TestSuite/TestSuite.Shared/Model/TestEntity.cs
  15. 2
      backend/tools/TestSuite/TestSuite.Shared/Model/TestEntityWithReferences.cs
  16. 8
      backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj

12
backend/src/Squidex.Web/Resources.cs

@ -209,21 +209,21 @@ namespace Squidex.Web
{
if (app == Permission.Any)
{
var falback = App;
var fallback = App;
if (!string.IsNullOrWhiteSpace(falback))
if (!string.IsNullOrWhiteSpace(fallback))
{
app = falback;
app = fallback;
}
}
if (schema == Permission.Any)
{
var falback = Controller.HttpContext.Features.Get<ISchemaFeature>()?.Schema.SchemaDef.Name;
var fallback = Controller.HttpContext.Features.Get<ISchemaFeature>()?.Schema.SchemaDef.Name;
if (!string.IsNullOrWhiteSpace(falback))
if (!string.IsNullOrWhiteSpace(fallback))
{
schema = falback;
schema = fallback;
}
}

119
backend/tools/TestSuite/TestSuite.ApiTests/AppClientsTests.cs

@ -0,0 +1,119 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
namespace TestSuite.ApiTests
{
public sealed class AppClientsTests : IClassFixture<ClientFixture>
{
private readonly string appName = Guid.NewGuid().ToString();
private readonly string id = Guid.NewGuid().ToString();
private readonly string clientRole = "Editor";
private readonly string clientName = "My Client";
public ClientFixture _ { get; }
public AppClientsTests(ClientFixture fixture)
{
_ = fixture;
}
[Fact]
public async Task Should_create_client()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 1: Create client.
var client = await CreateAsync();
// Should return client with correct name and id.
Assert.Equal(clientRole, client.Role);
Assert.Equal(id, client.Name);
}
[Fact]
public async Task Should_update_client()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 0: Create client.
var client = await CreateAsync();
// STEP 1: Update client name.
var updateNameRequest = new UpdateClientDto
{
Name = clientName,
AllowAnonymous = true,
ApiCallsLimit = 100,
ApiTrafficLimit = 200,
Role = "Owner"
};
var clients_2 = await _.Apps.PutClientAsync(appName, client.Id, updateNameRequest);
var client_2 = clients_2.Items.Find(x => x.Id == client.Id);
// Should update client name.
Assert.Equal(updateNameRequest.Name, client_2.Name);
Assert.Equal(updateNameRequest.AllowAnonymous, client_2.AllowAnonymous);
Assert.Equal(updateNameRequest.ApiCallsLimit, client_2.ApiCallsLimit);
Assert.Equal(updateNameRequest.ApiTrafficLimit, client_2.ApiTrafficLimit);
Assert.Equal(updateNameRequest.Role, client_2.Role);
}
[Fact]
public async Task Should_delete_client()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 0: Create client.
var client = await CreateAsync();
// STEP 1: Delete client
var clients_2 = await _.Apps.DeleteClientAsync(appName, client.Id);
// Should not return deleted client.
Assert.DoesNotContain(clients_2.Items, x => x.Id == client.Id);
}
private async Task<ClientDto> CreateAsync()
{
var createRequest = new CreateClientDto
{
Id = id
};
var clients = await _.Apps.PostClientAsync(appName, createRequest);
var client = clients.Items.Find(x => x.Id == id);
return client;
}
private async Task CreateAppAsync()
{
var createRequest = new CreateAppDto
{
Name = appName
};
await _.Apps.PostAppAsync(createRequest);
}
}
}

97
backend/tools/TestSuite/TestSuite.ApiTests/AppContributorsTests.cs

@ -0,0 +1,97 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
namespace TestSuite.ApiTests
{
public sealed class AppContributorsTests : IClassFixture<CreatedAppFixture>
{
private readonly string email = $"{Guid.NewGuid()}@squidex.io";
public CreatedAppFixture _ { get; }
public AppContributorsTests(CreatedAppFixture fixture)
{
_ = fixture;
}
[Fact]
public async Task Should_not_invite_contributor_if_flag_is_false()
{
// STEP 0: Do not invite contributors when flag is false.
var createRequest = new AssignContributorDto { ContributorId = "test@squidex.io" };
var ex = await Assert.ThrowsAsync<SquidexManagementException>(() =>
{
return _.Apps.PostContributorAsync(_.AppName, createRequest);
});
Assert.Equal(404, ex.StatusCode);
}
[Fact]
public async Task Should_invite_contributor()
{
// STEP 1: Assign contributor.
ContributorDto contributor_1 = await InviteAsync();
Assert.Equal("Developer", contributor_1?.Role);
}
[Fact]
public async Task Should_update_contributor()
{
// STEP 0: Assign contributor.
var contributor = await InviteAsync();
// STEP 1: Update contributor role.
var updateRequest = new AssignContributorDto
{
ContributorId = email, Role = "Owner"
};
var contributors_2 = await _.Apps.PostContributorAsync(_.AppName, updateRequest);
var contributor_2 = contributors_2.Items.Find(x => x.ContributorId == contributor.ContributorId);
Assert.Equal(updateRequest.Role, contributor_2?.Role);
}
[Fact]
public async Task Should_remove_contributor()
{
// STEP 0: Assign contributor.
var contributor = await InviteAsync();
// STEP 1: Remove contributor.
var contributors_2 = await _.Apps.DeleteContributorAsync(_.AppName, contributor.ContributorId);
Assert.DoesNotContain(contributors_2.Items, x => x.ContributorId == contributor.ContributorId);
}
private async Task<ContributorDto> InviteAsync()
{
var createInviteRequest = new AssignContributorDto
{
ContributorId = email,
Invite = true
};
var contributors = await _.Apps.PostContributorAsync(_.AppName, createInviteRequest);
var contributor = contributors.Items.Find(x => x.ContributorName == email);
return contributor;
}
}
}

175
backend/tools/TestSuite/TestSuite.ApiTests/AppLanguagesTests.cs

@ -0,0 +1,175 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
namespace TestSuite.ApiTests
{
public sealed class AppLanguagesTests : IClassFixture<ClientFixture>
{
private readonly string appName = Guid.NewGuid().ToString();
public ClientFixture _ { get; }
public AppLanguagesTests(ClientFixture fixture)
{
_ = fixture;
}
[Fact]
public async Task Should_add_language()
{
// STEP 0: Add app.
await CreateAppAsync();
// STEP 1: Add languages.
await AddLanguageAsync("de");
await AddLanguageAsync("it");
var languages_1 = await _.Apps.GetLanguagesAsync(appName);
Assert.Equal(new string[] { "en", "de", "it" }, languages_1.Items.Select(x => x.Iso2Code).ToArray());
}
[Fact]
public async Task Should_update_language()
{
// STEP 0: Add app.
await CreateAppAsync();
// STEP 1: Add languages.
await AddLanguageAsync("de");
await AddLanguageAsync("it");
// STEP 3: Update German language.
var updateRequest = new UpdateLanguageDto
{
Fallback = new List<string>
{
"it"
},
IsOptional = true
};
var languages_2 = await _.Apps.PutLanguageAsync(appName, "de", updateRequest);
var language_2_DE = languages_2.Items.Find(x => x.Iso2Code == "de");
Assert.Equal(updateRequest.Fallback, language_2_DE.Fallback);
Assert.Equal(updateRequest.IsOptional, language_2_DE.IsOptional);
}
[Fact]
public async Task Should_update_master_language()
{
// STEP 0: Add app.
await CreateAppAsync();
// STEP 1: Add languages.
await AddLanguageAsync("de");
await AddLanguageAsync("it");
// STEP 2: Update Italian language.
var updateRequest = new UpdateLanguageDto
{
Fallback = new List<string>
{
"de"
},
IsOptional = true
};
await _.Apps.PutLanguageAsync(appName, "it", updateRequest);
// STEP 3: Change master language to Italian.
var masterRequest = new UpdateLanguageDto
{
IsMaster = true
};
var languages_4 = await _.Apps.PutLanguageAsync(appName, "it", masterRequest);
var language_4_IT = languages_4.Items.Find(x => x.Iso2Code == "it");
var language_4_EN = languages_4.Items.Find(x => x.Iso2Code == "en");
Assert.True(language_4_IT.IsMaster);
// Old master language is unset.
Assert.False(language_4_EN.IsMaster);
// Master language cannot be optional.
Assert.False(language_4_IT.IsOptional);
// Fallback for new master language must be removed.
Assert.Empty(language_4_IT.Fallback);
}
[Fact]
public async Task Should_delete_language()
{
// STEP 0: Add app.
await CreateAppAsync();
// STEP 1: Add languages.
await AddLanguageAsync("de");
await AddLanguageAsync("it");
// STEP 2: Update Italian language.
var updateRequest = new UpdateLanguageDto
{
Fallback = new List<string>
{
"de"
},
IsOptional = true
};
await _.Apps.PutLanguageAsync(appName, "it", updateRequest);
// STEP 3: Remove language.
var languages_2 = await _.Apps.DeleteLanguageAsync(appName, "de");
var language_2_IT = languages_2.Items.Find(x => x.Iso2Code == "it");
// Fallback language must be removed.
Assert.Empty(language_2_IT.Fallback);
Assert.Equal(new string[] { "en", "it" }, languages_2.Items.Select(x => x.Iso2Code).ToArray());
}
private async Task CreateAppAsync()
{
var createRequest = new CreateAppDto
{
Name = appName
};
await _.Apps.PostAppAsync(createRequest);
}
private async Task AddLanguageAsync(string code)
{
var createRequest = new AddLanguageDto
{
Language = code
};
await _.Apps.PostLanguageAsync(appName, createRequest);
}
}
}

175
backend/tools/TestSuite/TestSuite.ApiTests/AppRolesTests.cs

@ -0,0 +1,175 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
namespace TestSuite.ApiTests
{
public sealed class AppRolesTests : IClassFixture<CreatedAppFixture>
{
private readonly string roleName = Guid.NewGuid().ToString();
private readonly string client = Guid.NewGuid().ToString();
private readonly string contributor = $"{Guid.NewGuid()}@squidex.io";
public CreatedAppFixture _ { get; }
public AppRolesTests(CreatedAppFixture fixture)
{
_ = fixture;
}
[Fact]
public async Task Should_create_role()
{
// STEP 1: Add role.
var role = await CreateRoleAsync(roleName);
// Should return role with correct name.
Assert.Empty(role.Permissions);
}
[Fact]
public async Task Should_create_role_with_buggy_name()
{
// STEP 1: Add role.
var role = await CreateRoleAsync($"{Guid.NewGuid()}/1");
// Should return role with correct name.
Assert.Empty(role.Permissions);
}
[Fact]
public async Task Should_update_role()
{
// STEP 1: Add role.
var role = await CreateRoleAsync(roleName);
// STEP 2: Update role.
var updateRequest = new UpdateRoleDto
{
Permissions = new List<string> { "a", "b" }
};
var roles_2 = await _.Apps.PutRoleAsync(_.AppName, roleName, updateRequest);
var role_2 = roles_2.Items.Find(x => x.Name == roleName);
// Should return role with correct name.
Assert.Equal(updateRequest.Permissions, role_2.Permissions);
}
[Fact]
public async Task Should_prevent_deletion_if_client_assigned()
{
// STEP 1: Add role.
var role = await CreateRoleAsync(roleName);
// STEP 2 Assign client and contributor.
await _.Apps.PostClientAsync(_.AppName, new CreateClientDto { Id = client });
await AssignClient(roleName);
var roles_2 = await _.Apps.GetRolesAsync(_.AppName);
var role_2 = roles_2.Items.Find(x => x.Name == roleName);
// Should return role with correct number of users and clients.
Assert.Equal(1, role_2.NumClients);
Assert.Equal(0, role_2.NumContributors);
// STEP 4: Try to delete role.
var ex = await Assert.ThrowsAsync<SquidexManagementException<ErrorDto>>(() =>
{
return _.Apps.DeleteRoleAsync(_.AppName, roleName);
});
Assert.Equal(400, ex.StatusCode);
// STEP 5: AssignClient client.
await AssignClient("Developer");
var roles_3 = await _.Apps.DeleteRoleAsync(_.AppName, roleName);
Assert.DoesNotContain(roles_3.Items, x => x.Name == roleName);
}
[Fact]
public async Task Should_prevent_deletion_if_contributor_assigned()
{
// STEP 1: Add role.
var role = await CreateRoleAsync(roleName);
// STEP 2 Assign contributor.
await AssignContributor(roleName);
var roles_2 = await _.Apps.GetRolesAsync(_.AppName);
var role_2 = roles_2.Items.Find(x => x.Name == roleName);
// Should return role with correct number of users and clients.
Assert.Equal(0, role_2.NumClients);
Assert.Equal(1, role_2.NumContributors);
// STEP 4: Try to delete role.
var ex = await Assert.ThrowsAsync<SquidexManagementException<ErrorDto>>(() =>
{
return _.Apps.DeleteRoleAsync(_.AppName, roleName);
});
Assert.Equal(400, ex.StatusCode);
// STEP 5: Remove role after contributor removed.
await AssignContributor("Developer");
var roles_3 = await _.Apps.DeleteRoleAsync(_.AppName, roleName);
Assert.DoesNotContain(roles_3.Items, x => x.Name == roleName);
}
private async Task AssignContributor(string role = null)
{
var assignRequest = new AssignContributorDto
{
ContributorId = contributor, Role = role, Invite = true
};
await _.Apps.PostContributorAsync(_.AppName, assignRequest);
}
private async Task AssignClient(string role = null)
{
var updateRequest = new UpdateClientDto
{
Role = role
};
await _.Apps.PutClientAsync(_.AppName, client, updateRequest);
}
private async Task<RoleDto> CreateRoleAsync(string name)
{
var createRequest = new AddRoleDto
{
Name = name
};
var roles = await _.Apps.PostRoleAsync(_.AppName, createRequest);
var role = roles.Items.Find(x => x.Name == name);
return role;
}
}
}

283
backend/tools/TestSuite/TestSuite.ApiTests/AppTests.cs

@ -33,22 +33,35 @@ namespace TestSuite.ApiTests
}
[Fact]
public async Task Should_manage_app_properties()
public async Task Should_set_label()
{
var newLabel = Guid.NewGuid().ToString();
var newDescription = Guid.NewGuid().ToString();
// STEP 1: Update app
var updateRequest = new UpdateAppDto
{
Label = Guid.NewGuid().ToString()
};
var app_1 = await _.Apps.PutAppAsync(_.AppName, updateRequest);
Assert.Equal(updateRequest.Label, app_1.Label);
}
[Fact]
public async Task Should_set_description()
{
// STEP 1: Update app
var updateRequest = new UpdateAppDto { Label = newLabel, Description = newDescription };
var updateRequest = new UpdateAppDto
{
Description = Guid.NewGuid().ToString()
};
var app_1 = await _.Apps.PutAppAsync(_.AppName, updateRequest);
Assert.Equal(newLabel, app_1.Label);
Assert.Equal(newDescription, app_1.Description);
Assert.Equal(updateRequest.Description, app_1.Description);
}
[Fact]
public async Task Should_manage_image()
public async Task Should_upload_image()
{
// STEP 1: Upload image.
await using (var stream = new FileStream("Assets/logo-squared.png", FileMode.Open))
@ -77,106 +90,28 @@ namespace TestSuite.ApiTests
// Should dowload with correct size.
Assert.True(downloaded.Length < stream.Length);
}
// STEP 3: Delete Image.
var app_2 = await _.Apps.DeleteImageAsync(_.AppName);
// Should contain image link.
Assert.False(app_2._links.ContainsKey("image"));
}
[Fact]
public async Task Should_manage_clients()
public async Task Should_delete_image()
{
var clientId = Guid.NewGuid().ToString();
var clientName = "My Client";
var clientRole1 = "Editor";
var clientRole2 = "Owner";
// STEP 1: Create client.
var createRequest = new CreateClientDto { Id = clientId };
var clients_1 = await _.Apps.PostClientAsync(_.AppName, createRequest);
var client_1 = clients_1.Items.FirstOrDefault(x => x.Id == clientId);
// Should return client with correct name and id.
Assert.Equal(clientRole1, client_1.Role);
Assert.Equal(clientId, client_1.Name);
// STEP 2: Update client name.
var updateNameRequest = new UpdateClientDto { Name = clientName };
var clients_2 = await _.Apps.PutClientAsync(_.AppName, clientId, updateNameRequest);
var client_2 = clients_2.Items.FirstOrDefault(x => x.Id == clientId);
// Should update client name.
Assert.Equal(clientName, client_2.Name);
// STEP 3: Update client role.
var updateRoleRequest = new UpdateClientDto { Role = clientRole2 };
var clients_3 = await _.Apps.PutClientAsync(_.AppName, clientId, updateRoleRequest);
var client_3 = clients_3.Items.FirstOrDefault(x => x.Id == clientId);
// Should update client role.
Assert.Equal(clientRole2, client_3.Role);
// STEP 4: Delete client
var clients_4 = await _.Apps.DeleteClientAsync(_.AppName, clientId);
var client_4 = clients_4.Items.FirstOrDefault(x => x.Id == clientId);
// Should not return deleted client.
Assert.Null(client_4);
}
[Fact]
public async Task Should_manage_contributors()
{
var contributorEmail = "sebastian@squidex.io";
var contributorRole1 = "Developer";
var contributorRole2 = "Owner";
// STEP 0: Do not invite contributors when flag is false.
var createRequest = new AssignContributorDto { ContributorId = "test@squidex.io" };
var ex = await Assert.ThrowsAsync<SquidexManagementException>(() =>
// STEP 1: Upload image.
await using (var stream = new FileStream("Assets/logo-squared.png", FileMode.Open))
{
return _.Apps.PostContributorAsync(_.AppName, createRequest);
});
Assert.Equal(404, ex.StatusCode);
// STEP 1: Assign contributor.
var createInviteRequest = new AssignContributorDto { ContributorId = contributorEmail, Invite = true };
var contributors_1 = await _.Apps.PostContributorAsync(_.AppName, createInviteRequest);
var contributor_1 = contributors_1.Items.FirstOrDefault(x => x.ContributorName == contributorEmail);
// Should return contributor with correct email.
Assert.Equal(contributorRole1, contributor_1?.Role);
// STEP 2: Update contributor role.
var updateRequest = new AssignContributorDto { ContributorId = contributorEmail, Role = contributorRole2 };
var file = new FileParameter(stream, "logo-squared.png", "image/png");
var contributors_2 = await _.Apps.PostContributorAsync(_.AppName, updateRequest);
var contributor_2 = contributors_2.Items.FirstOrDefault(x => x.ContributorId == contributor_1.ContributorId);
var app_1 = await _.Apps.UploadImageAsync(_.AppName, file);
// Should return contributor with correct role.
Assert.Equal(contributorRole2, contributor_2?.Role);
// Should contain image link.
Assert.True(app_1._links.ContainsKey("image"));
}
// STEP 3: Remove contributor.
var contributors_3 = await _.Apps.DeleteContributorAsync(_.AppName, contributor_2.ContributorId);
var contributor_3 = contributors_3.Items.FirstOrDefault(x => x.ContributorId == contributor_1.ContributorId);
// STEP 2: Delete Image.
var app_2 = await _.Apps.DeleteImageAsync(_.AppName);
// Should not return deleted contributor.
Assert.Null(contributor_3);
// Should contain image link.
Assert.False(app_2._links.ContainsKey("image"));
}
[Fact]
@ -191,7 +126,7 @@ namespace TestSuite.ApiTests
var createRequest = new AddRoleDto { Name = roleName };
var roles_1 = await _.Apps.PostRoleAsync(_.AppName, createRequest);
var role_1 = roles_1.Items.FirstOrDefault(x => x.Name == roleName);
var role_1 = roles_1.Items.Find(x => x.Name == roleName);
// Should return role with correct name.
Assert.Empty(role_1.Permissions);
@ -201,7 +136,7 @@ namespace TestSuite.ApiTests
var updateRequest = new UpdateRoleDto { Permissions = new List<string> { "a", "b" } };
var roles_2 = await _.Apps.PutRoleAsync(_.AppName, roleName, updateRequest);
var role_2 = roles_2.Items.FirstOrDefault(x => x.Name == roleName);
var role_2 = roles_2.Items.Find(x => x.Name == roleName);
// Should return role with correct name.
Assert.Equal(updateRequest.Permissions, role_2.Permissions);
@ -217,7 +152,7 @@ namespace TestSuite.ApiTests
await _.Apps.PostContributorAsync(_.AppName, new AssignContributorDto { ContributorId = roleContributor1, Role = roleName, Invite = true });
var roles_3 = await _.Apps.GetRolesAsync(_.AppName);
var role_3 = roles_3.Items.FirstOrDefault(x => x.Name == roleName);
var role_3 = roles_3.Items.Find(x => x.Name == roleName);
// Should return role with correct number of users and clients.
Assert.Equal(1, role_3.NumClients);
@ -245,164 +180,38 @@ namespace TestSuite.ApiTests
await _.Apps.DeleteRoleAsync(_.AppName, roleName);
var roles_4 = await _.Apps.GetRolesAsync(_.AppName);
var role_4 = roles_4.Items.FirstOrDefault(x => x.Name == roleName);
var role_4 = roles_4.Items.Find(x => x.Name == roleName);
// Should not return deleted role.
Assert.Null(role_4);
}
[Fact]
public async Task Should_manage_languages()
public async Task Should_get_settings()
{
var appName = Guid.NewGuid().ToString();
// STEP 1: Add app.
var createRequest = new CreateAppDto { Name = appName };
await _.Apps.PostAppAsync(createRequest);
// STEP 2: Add languages.
await _.Apps.PostLanguageAsync(appName, new AddLanguageDto { Language = "de" });
await _.Apps.PostLanguageAsync(appName, new AddLanguageDto { Language = "it" });
await _.Apps.PostLanguageAsync(appName, new AddLanguageDto { Language = "fr" });
var languages_1 = await _.Apps.GetLanguagesAsync(appName);
var language_1_EN = languages_1.Items.FirstOrDefault(x => x.Iso2Code == "en");
Assert.Equal(new string[] { "en", "de", "fr", "it" }, languages_1.Items.Select(x => x.Iso2Code).ToArray());
Assert.True(language_1_EN.IsMaster);
// STEP 3: Update German language.
var updateRequest1 = new UpdateLanguageDto
{
Fallback = new string[]
{
"fr",
"it"
},
IsOptional = true
};
var languages_2 = await _.Apps.PutLanguageAsync(appName, "de", updateRequest1);
var language_2_DE = languages_2.Items.FirstOrDefault(x => x.Iso2Code == "de");
Assert.Equal(new string[] { "fr", "it" }, language_2_DE.Fallback.ToArray());
Assert.True(language_2_DE.IsOptional);
// STEP 4: Update Italian language.
var updateRequest2 = new UpdateLanguageDto
{
Fallback = new string[]
{
"fr",
"de"
}
};
var languages_3 = await _.Apps.PutLanguageAsync(appName, "it", updateRequest2);
var language_3_DE = languages_3.Items.FirstOrDefault(x => x.Iso2Code == "it");
Assert.Equal(new string[] { "fr", "de" }, language_3_DE.Fallback.ToArray());
// STEP 5: Change master language.
var masterRequest = new UpdateLanguageDto { IsMaster = true };
var languages_4 = await _.Apps.PutLanguageAsync(appName, "it", masterRequest);
var language_4_IT = languages_4.Items.FirstOrDefault(x => x.Iso2Code == "it");
var language_4_EN = languages_4.Items.FirstOrDefault(x => x.Iso2Code == "en");
Assert.True(language_4_IT.IsMaster);
Assert.False(language_4_IT.IsOptional);
Assert.False(language_4_EN.IsMaster);
Assert.Empty(language_4_IT.Fallback);
Assert.Equal(new string[] { "it", "de", "en", "fr" }, languages_4.Items.Select(x => x.Iso2Code).ToArray());
// STEP 6: Remove language.
var languages_5 = await _.Apps.DeleteLanguageAsync(appName, "fr");
var language_5_DE = languages_5.Items.FirstOrDefault(x => x.Iso2Code == "de");
// STEP 1: Get initial settings.
var settings_0 = await _.Apps.GetSettingsAsync(_.AppName);
Assert.Equal(new string[] { "it" }, language_5_DE.Fallback.ToArray());
Assert.Equal(new string[] { "it", "de", "en" }, languages_5.Items.Select(x => x.Iso2Code).ToArray());
Assert.NotEmpty(settings_0.Patterns);
}
[Fact]
public async Task Should_manage_workflows()
public async Task Should_update_settings()
{
var workflowName = Guid.NewGuid().ToString();
// STEP 0: Create workflow.
var createRequest = new AddWorkflowDto
{
Name = workflowName
};
var workflows_1 = await _.Apps.PostWorkflowAsync(_.AppName, createRequest);
var workflow_1 = workflows_1.Items.FirstOrDefault(x => x.Name == workflowName);
Assert.NotNull(workflow_1);
Assert.NotNull(workflow_1.Name);
Assert.Equal(3, workflow_1.Steps.Count);
// STEP 1: Update workflow.
var updateRequest = new UpdateWorkflowDto
// STEP 1: Update settings with new state.
var updateRequest = new UpdateAppSettingsDto
{
Initial = "Draft",
Steps = new Dictionary<string, WorkflowStepDto>
Patterns = new List<PatternDto>
{
["Draft"] = new WorkflowStepDto
{
Transitions = new Dictionary<string, WorkflowTransitionDto>
{
["Published"] = new WorkflowTransitionDto()
}
},
["Published"] = new WorkflowStepDto(),
new PatternDto { Name = "pattern", Regex = ".*" }
},
Name = workflowName
};
var workflows_2 = await _.Apps.PutWorkflowAsync(_.AppName, workflow_1.Id, updateRequest);
var workflow_2 = workflows_2.Items.FirstOrDefault(x => x.Name == workflowName);
Assert.NotNull(workflow_2);
Assert.NotNull(workflow_2.Name);
Assert.Equal(2, workflow_2.Steps.Count);
// STEP 2: Delete workflow.
var workflows_3 = await _.Apps.DeleteWorkflowAsync(_.AppName, workflow_1.Id);
var workflow_3 = workflows_3.Items.FirstOrDefault(x => x.Name == workflowName);
// Should not return deleted workflow.
Assert.Null(workflow_3);
}
[Fact]
public async Task Should_manage_settings()
{
// STEP 1: Get initial settings.
var settings_0 = await _.Apps.GetAppSettingsAsync(_.AppName);
Assert.NotEmpty(settings_0.Patterns);
// STEP 2: Update settings with new state.
var updateRequest = new UpdateAppSettingsDto
{
Patterns = settings_0.Patterns,
Editors = new List<EditorDto>
{
new EditorDto { Name = "editor", Url = "http://squidex.io/path/to/editor" }
}
};
var settings_1 = await _.Apps.PutAppSettingsAsync(_.AppName, updateRequest);
var settings_1 = await _.Apps.PutSettingsAsync(_.AppName, updateRequest);
Assert.NotEmpty(settings_1.Patterns);
Assert.NotEmpty(settings_1.Editors);

121
backend/tools/TestSuite/TestSuite.ApiTests/AppWorkflowsTest.cs

@ -0,0 +1,121 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
namespace TestSuite.ApiTests
{
public sealed class AppWorkflowsTests : IClassFixture<ClientFixture>
{
private readonly string appName = Guid.NewGuid().ToString();
private readonly string name = Guid.NewGuid().ToString();
public ClientFixture _ { get; }
public AppWorkflowsTests(ClientFixture fixture)
{
_ = fixture;
}
[Fact]
public async Task Should_create_workflow()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 1: Create workflow.
var workflow = await CreateAsync();
Assert.NotNull(workflow);
Assert.NotNull(workflow.Name);
Assert.Equal(3, workflow.Steps.Count);
}
[Fact]
public async Task Should_update_workflow()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 0: Create workflow.
var workflow = await CreateAsync();
// STEP 1: Update workflow.
var updateRequest = new UpdateWorkflowDto
{
Initial = "Draft",
Steps = new Dictionary<string, WorkflowStepDto>
{
["Draft"] = new WorkflowStepDto
{
Transitions = new Dictionary<string, WorkflowTransitionDto>
{
["Published"] = new WorkflowTransitionDto()
}
},
["Published"] = new WorkflowStepDto(),
},
Name = name
};
var workflows_2 = await _.Apps.PutWorkflowAsync(appName, workflow.Id, updateRequest);
var workflow_2 = workflows_2.Items.Find(x => x.Name == name);
Assert.NotNull(workflow_2);
Assert.NotNull(workflow_2.Name);
Assert.Equal(2, workflow_2.Steps.Count);
}
[Fact]
public async Task Should_delete_workflow()
{
// STEP 0: Create app.
await CreateAppAsync();
// STEP 0: Create workflow.
var workflow = await CreateAsync();
// STEP 1: Delete workflow.
var workflows_2 = await _.Apps.DeleteWorkflowAsync(appName, workflow.Id);
Assert.DoesNotContain(workflows_2.Items, x => x.Name == name);
}
private async Task<WorkflowDto> CreateAsync()
{
var createRequest = new AddWorkflowDto
{
Name = name
};
var workflows = await _.Apps.PostWorkflowAsync(appName, createRequest);
var workflow = workflows.Items.Find(x => x.Name == name);
return workflow;
}
private async Task CreateAppAsync()
{
var createRequest = new CreateAppDto
{
Name = appName
};
await _.Apps.PostAppAsync(createRequest);
}
}
}

2
backend/tools/TestSuite/TestSuite.ApiTests/ContentCleanupTests.cs

@ -43,7 +43,7 @@ namespace TestSuite.ApiTests
// STEP 3: Delete a field from schema.
await _.Schemas.DeleteFieldAsync(_.AppName, schema.Name, schema.Fields.ElementAt(1).FieldId);
await _.Schemas.DeleteFieldAsync(_.AppName, schema.Name, schema.Fields[1].FieldId);
// STEP 4: Make any update.

41
backend/tools/TestSuite/TestSuite.ApiTests/ContentUpdateTests.cs

@ -12,6 +12,7 @@ using TestSuite.Fixtures;
using TestSuite.Model;
using Xunit;
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row
@ -694,5 +695,45 @@ namespace TestSuite.ApiTests
Assert.Equal("singleton", content_2.Data["my-field"]["iv"]);
}
[Fact]
public async Task Should_get_content_by_version()
{
TestEntity content = null;
try
{
// STEP 1: Create a new item.
content = await _.Contents.CreateAsync(new TestEntityData { Number = 1 }, true);
// STEP 2: Update content.
content = await _.Contents.UpdateAsync(content.Id, new TestEntityData { Number = 2 });
// STEP 3: Get current version.
var content_latest = await _.Contents.GetAsync(content.Id);
Assert.Equal(2, content_latest.Data.Number);
// STEP 4: Get current version.
var data_2 = await _.Contents.GetDataAsync(content.Id, content.Version);
Assert.Equal(2, data_2.Number);
// STEP 4: Get previous version
var data_1 = await _.Contents.GetDataAsync(content.Id, content.Version - 1);
Assert.Equal(1, data_1.Number);
}
finally
{
if (content != null)
{
await _.Contents.DeleteAsync(content.Id);
}
}
}
}
}

1
backend/tools/TestSuite/TestSuite.ApiTests/SchemaTests.cs

@ -9,6 +9,7 @@ using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures;
using Xunit;
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row

2
backend/tools/TestSuite/TestSuite.ApiTests/Setup.cs

@ -7,4 +7,4 @@
using Xunit;
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]

4
backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj

@ -14,11 +14,11 @@
<None Remove="Assets\SampleImage_WEBP_350kb - Copy.webp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="1.0.676">
<PackageReference Include="Meziantou.Analyzer" Version="1.0.679">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

4
backend/tools/TestSuite/TestSuite.LoadTests/TestSuite.LoadTests.csproj

@ -6,11 +6,11 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="1.0.676">
<PackageReference Include="Meziantou.Analyzer" Version="1.0.679">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

2
backend/tools/TestSuite/TestSuite.Shared/Model/TestEntity.cs

@ -15,7 +15,7 @@ namespace TestSuite.Model
{
public const int ScriptTrigger = -99;
public static async Task<SchemaDetailsDto> CreateSchemaAsync(ISchemasClient schemas, string appName, string name)
public static async Task<SchemaDto> CreateSchemaAsync(ISchemasClient schemas, string appName, string name)
{
var schema = await schemas.PostSchemaAsync(appName, new CreateSchemaDto
{

2
backend/tools/TestSuite/TestSuite.Shared/Model/TestEntityWithReferences.cs

@ -13,7 +13,7 @@ namespace TestSuite.Model
{
public sealed class TestEntityWithReferences : Content<TestEntityWithReferencesData>
{
public static async Task<SchemaDetailsDto> CreateSchemaAsync(ISchemasClient schemas, string appName, string name)
public static async Task<SchemaDto> CreateSchemaAsync(ISchemasClient schemas, string appName, string name)
{
var schema = await schemas.PostSchemaAsync(appName, new CreateSchemaDto
{

8
backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj

@ -6,12 +6,12 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.1">
<PackageReference Include="Fody" Version="6.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Lazy.Fody" Version="1.9.0" PrivateAssets="all" />
<PackageReference Include="Meziantou.Analyzer" Version="1.0.676">
<PackageReference Include="Lazy.Fody" Version="1.10.0" PrivateAssets="all" />
<PackageReference Include="Meziantou.Analyzer" Version="1.0.679">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -21,7 +21,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.ClientLibrary" Version="7.0.0" />
<PackageReference Include="Squidex.ClientLibrary" Version="7.7.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>

Loading…
Cancel
Save