Skip to content

Commit 2b18315

Browse files
ayush3797severussundarseantleonard
authored
Multiple-Create : Feature (#2122)
## Why make this change? - All code changes for **Multiple Create** feature was being merged into `dev/NestedMutations` branch. - This PR attempts to merge all these changes to the `main` branch in preparation for the `0.12.* rc1` release ## What is this change? - Right now, `dev/NestedMutations` branch contains the code changes for the following components of Multiple Create feature - Schema Generation - #1902 - AuthZ - #1943 - Feature flag - CLI changes #1983 - Feature flag - Re-naming changes #2103 - Feature flag - Engine changes #2116 - Each specified PR was reviewed before merging into `dev/NestedMutations` branch. - This PR aims to merge all the changes into `main` branch ## How was this tested? - [x] Unit, Integration and Manual tests were performed on each PR before merging into `dev/NestedMutations` --------- Co-authored-by: Shyam Sundar J <[email protected]> Co-authored-by: Sean Leonard <[email protected]>
1 parent 5883ab8 commit 2b18315

File tree

70 files changed

+4537
-479
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+4537
-479
lines changed

config-generators/mssql-commands.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add stocks_price --config "dab-config.MsSql.json" --source stocks_price --permis
1414
update stocks_price --config "dab-config.MsSql.json" --permissions "anonymous:read"
1515
update stocks_price --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_ColumnForbidden:read" --fields.exclude "price"
1616
update stocks_price --config "dab-config.MsSql.json" --permissions "TestNestedFilterFieldIsNull_EntityReadForbidden:create"
17+
update stocks_price --config "dab-config.MsSql.json" --permissions "test_role_with_excluded_fields_on_create:create,read,update,delete"
1718
add Tree --config "dab-config.MsSql.json" --source trees --permissions "anonymous:create,read,update,delete"
1819
add Shrub --config "dab-config.MsSql.json" --source trees --permissions "anonymous:create,read,update,delete" --rest plants
1920
add Fungus --config "dab-config.MsSql.json" --source fungi --permissions "anonymous:create,read,update,delete" --graphql "fungus:fungi"
@@ -65,6 +66,8 @@ update Publisher --config "dab-config.MsSql.json" --permissions "database_policy
6566
update Publisher --config "dab-config.MsSql.json" --permissions "database_policy_tester:update" --policy-database "@item.id ne 1234"
6667
update Publisher --config "dab-config.MsSql.json" --permissions "database_policy_tester:create" --policy-database "@item.name ne 'New publisher'"
6768
update Stock --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
69+
update Stock --config "dab-config.MsSql.json" --permissions "test_role_with_excluded_fields_on_create:read,update,delete"
70+
update Stock --config "dab-config.MsSql.json" --permissions "test_role_with_excluded_fields_on_create:create" --fields.exclude "piecesAvailable"
6871
update Stock --config "dab-config.MsSql.json" --rest commodities --graphql true --relationship stocks_price --target.entity stocks_price --cardinality one
6972
update Book --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete"
7073
update Book --config "dab-config.MsSql.json" --relationship publishers --target.entity Publisher --cardinality one
@@ -112,6 +115,7 @@ update WebsiteUser --config "dab-config.MsSql.json" --permissions "authenticated
112115
update Revenue --config "dab-config.MsSql.json" --permissions "database_policy_tester:create" --policy-database "@item.revenue gt 1000"
113116
update Comic --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship myseries --target.entity series --cardinality one
114117
update series --config "dab-config.MsSql.json" --relationship comics --target.entity Comic --cardinality many
118+
update stocks_price --config "dab-config.MsSql.json" --relationship Stock --target.entity Stock --cardinality one
115119
update Broker --config "dab-config.MsSql.json" --permissions "authenticated:create,update,read,delete" --graphql false
116120
update Tree --config "dab-config.MsSql.json" --rest true --graphql false --permissions "authenticated:create,read,update,delete" --map "species:Scientific Name,region:United State's Region"
117121
update Shrub --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --map "species:fancyName"

schemas/dab.draft.schema.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,25 @@
175175
"enabled": {
176176
"type": "boolean",
177177
"description": "Allow enabling/disabling GraphQL requests for all entities."
178+
},
179+
"multiple-mutations": {
180+
"type": "object",
181+
"description": "Configuration properties for multiple mutation operations",
182+
"additionalProperties": false,
183+
"properties": {
184+
"create":{
185+
"type": "object",
186+
"description": "Options for multiple create operations",
187+
"additionalProperties": false,
188+
"properties": {
189+
"enabled": {
190+
"type": "boolean",
191+
"description": "Allow enabling/disabling multiple create operations for all entities.",
192+
"default": false
193+
}
194+
}
195+
}
196+
}
178197
}
179198
}
180199
},

src/Cli.Tests/ConfigGeneratorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public void TestSpecialCharactersInConnectionString()
162162
""enabled"": true,
163163
""path"": ""/An_"",
164164
""allow-introspection"": true
165-
},
165+
},
166166
""host"": {
167167
""cors"": {
168168
""origins"": [],

src/Cli.Tests/EndToEndTests.cs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,90 @@ public void TestInitializingRestAndGraphQLGlobalSettings()
131131
Assert.IsTrue(runtimeConfig.Runtime.GraphQL?.Enabled);
132132
}
133133

134+
/// <summary>
135+
/// Test to validate the usage of --graphql.multiple-create.enabled option of the init command for all database types.
136+
///
137+
/// 1. Behavior for database types other than MsSQL:
138+
/// - Irrespective of whether the --graphql.multiple-create.enabled option is used or not, fields related to multiple-create will NOT be written to the config file.
139+
/// - As a result, after deserialization of such a config file, the Runtime.GraphQL.MultipleMutationOptions is expected to be null.
140+
/// 2. Behavior for MsSQL database type:
141+
///
142+
/// a. When --graphql.multiple-create.enabled option is used
143+
/// - In this case, the fields related to multiple mutation and multiple create operations will be written to the config file.
144+
/// "multiple-mutations": {
145+
/// "create": {
146+
/// "enabled": true/false
147+
/// }
148+
/// }
149+
/// After deserializing such a config file, the Runtime.GraphQL.MultipleMutationOptions is expected to be non-null and the value of the "enabled" field is expected to be the same as the value passed in the init command.
150+
///
151+
/// b. When --graphql.multiple-create.enabled option is not used
152+
/// - In this case, fields related to multiple mutation and multiple create operations will NOT be written to the config file.
153+
/// - As a result, after deserialization of such a config file, the Runtime.GraphQL.MultipleMutationOptions is expected to be null.
154+
///
155+
/// </summary>
156+
/// <param name="isMultipleCreateEnabled">Value interpreted by the CLI for '--graphql.multiple-create.enabled' option of the init command.
157+
/// When not used, CLI interprets the value for the option as CliBool.None
158+
/// When used with true/false, CLI interprets the value as CliBool.True/CliBool.False respectively.
159+
/// </param>
160+
/// <param name="expectedValueForMultipleCreateEnabledFlag"> Expected value for the multiple create enabled flag in the config file.</param>
161+
[DataTestMethod]
162+
[DataRow(CliBool.True, "mssql", DatabaseType.MSSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for MsSql database type")]
163+
[DataRow(CliBool.False, "mssql", DatabaseType.MSSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for MsSql database type")]
164+
[DataRow(CliBool.None, "mssql", DatabaseType.MSSQL, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for MsSql database type")]
165+
[DataRow(CliBool.True, "mysql", DatabaseType.MySQL, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for MySql database type")]
166+
[DataRow(CliBool.False, "mysql", DatabaseType.MySQL, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for MySql database type")]
167+
[DataRow(CliBool.None, "mysql", DatabaseType.MySQL, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for MySql database type")]
168+
[DataRow(CliBool.True, "postgresql", DatabaseType.PostgreSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for PostgreSql database type")]
169+
[DataRow(CliBool.False, "postgresql", DatabaseType.PostgreSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for PostgreSql database type")]
170+
[DataRow(CliBool.None, "postgresql", DatabaseType.PostgreSQL, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for PostgreSql database type")]
171+
[DataRow(CliBool.True, "dwsql", DatabaseType.DWSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for dwsql database type")]
172+
[DataRow(CliBool.False, "dwsql", DatabaseType.DWSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for dwsql database type")]
173+
[DataRow(CliBool.None, "dwsql", DatabaseType.DWSQL, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for dwsql database type")]
174+
[DataRow(CliBool.True, "cosmosdb_nosql", DatabaseType.CosmosDB_NoSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for cosmosdb_nosql database type")]
175+
[DataRow(CliBool.False, "cosmosdb_nosql", DatabaseType.CosmosDB_NoSQL, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for cosmosdb_nosql database type")]
176+
[DataRow(CliBool.None, "cosmosdb_nosql", DatabaseType.CosmosDB_NoSQL, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for cosmosdb_nosql database type")]
177+
public void TestEnablingMultipleCreateOperation(CliBool isMultipleCreateEnabled, string dbType, DatabaseType expectedDbType)
178+
{
179+
List<string> args = new() { "init", "-c", TEST_RUNTIME_CONFIG_FILE, "--connection-string", SAMPLE_TEST_CONN_STRING, "--database-type", dbType };
180+
181+
if (string.Equals("cosmosdb_nosql", dbType, StringComparison.OrdinalIgnoreCase))
182+
{
183+
List<string> cosmosNoSqlArgs = new() { "--cosmosdb_nosql-database",
184+
"graphqldb", "--cosmosdb_nosql-container", "planet", "--graphql-schema", TEST_SCHEMA_FILE};
185+
args.AddRange(cosmosNoSqlArgs);
186+
}
187+
188+
if (isMultipleCreateEnabled is not CliBool.None)
189+
{
190+
args.Add("--graphql.multiple-create.enabled");
191+
args.Add(isMultipleCreateEnabled.ToString()!);
192+
}
193+
194+
Program.Execute(args.ToArray(), _cliLogger!, _fileSystem!, _runtimeConfigLoader!);
195+
196+
Assert.IsTrue(_runtimeConfigLoader!.TryLoadConfig(
197+
TEST_RUNTIME_CONFIG_FILE,
198+
out RuntimeConfig? runtimeConfig,
199+
replaceEnvVar: true));
200+
201+
Assert.IsNotNull(runtimeConfig);
202+
Assert.AreEqual(expectedDbType, runtimeConfig.DataSource.DatabaseType);
203+
Assert.IsNotNull(runtimeConfig.Runtime);
204+
Assert.IsNotNull(runtimeConfig.Runtime.GraphQL);
205+
if (runtimeConfig.DataSource.DatabaseType is DatabaseType.MSSQL && isMultipleCreateEnabled is not CliBool.None)
206+
{
207+
Assert.IsNotNull(runtimeConfig.Runtime.GraphQL.MultipleMutationOptions);
208+
Assert.IsNotNull(runtimeConfig.Runtime.GraphQL.MultipleMutationOptions.MultipleCreateOptions);
209+
bool expectedValueForMultipleCreateEnabled = isMultipleCreateEnabled == CliBool.True;
210+
Assert.AreEqual(expectedValueForMultipleCreateEnabled, runtimeConfig.Runtime.GraphQL.MultipleMutationOptions.MultipleCreateOptions.Enabled);
211+
}
212+
else
213+
{
214+
Assert.IsNull(runtimeConfig.Runtime.GraphQL.MultipleMutationOptions, message: "MultipleMutationOptions is expected to be null because a) DB type is not MsSQL or b) Either --graphql.multiple-create.enabled option was not used or no value was provided.");
215+
}
216+
}
217+
134218
/// <summary>
135219
/// Test to verify adding a new Entity.
136220
/// </summary>

src/Cli.Tests/InitTests.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,89 @@ public Task GraphQLPathWithoutStartingSlashWillHaveItAdded()
409409
return ExecuteVerifyTest(options);
410410
}
411411

412+
/// <summary>
413+
/// Test to validate the contents of the config file generated when init command is used with --graphql.multiple-create.enabled flag option for different database types.
414+
///
415+
/// 1. For database types other than MsSQL:
416+
/// - Irrespective of whether the --graphql.multiple-create.enabled option is used or not, fields related to multiple-create will NOT be written to the config file.
417+
///
418+
/// 2. For MsSQL database type:
419+
/// a. When --graphql.multiple-create.enabled option is used
420+
/// - In this case, the fields related to multiple mutation and multiple create operations will be written to the config file.
421+
/// "multiple-mutations": {
422+
/// "create": {
423+
/// "enabled": true/false
424+
/// }
425+
/// }
426+
///
427+
/// b. When --graphql.multiple-create.enabled option is not used
428+
/// - In this case, fields related to multiple mutation and multiple create operations will NOT be written to the config file.
429+
///
430+
/// </summary>
431+
[DataTestMethod]
432+
[DataRow(DatabaseType.MSSQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for MsSQL database type")]
433+
[DataRow(DatabaseType.MSSQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for MsSQL database type")]
434+
[DataRow(DatabaseType.MSSQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for MsSQL database type")]
435+
[DataRow(DatabaseType.PostgreSQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for PostgreSQL database type")]
436+
[DataRow(DatabaseType.PostgreSQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for PostgreSQL database type")]
437+
[DataRow(DatabaseType.PostgreSQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for PostgreSQL database type")]
438+
[DataRow(DatabaseType.MySQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for MySQL database type")]
439+
[DataRow(DatabaseType.MySQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for MySQL database type")]
440+
[DataRow(DatabaseType.MySQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for MySQL database type")]
441+
[DataRow(DatabaseType.CosmosDB_NoSQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for CosmosDB_NoSQL database type")]
442+
[DataRow(DatabaseType.CosmosDB_NoSQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for CosmosDB_NoSQL database type")]
443+
[DataRow(DatabaseType.CosmosDB_NoSQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for CosmosDB_NoSQL database type")]
444+
[DataRow(DatabaseType.CosmosDB_PostgreSQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for CosmosDB_PostgreSQL database type")]
445+
[DataRow(DatabaseType.CosmosDB_PostgreSQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for CosmosDB_PostgreSQL database type")]
446+
[DataRow(DatabaseType.CosmosDB_PostgreSQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for CosmosDB_PostgreSQL database type")]
447+
[DataRow(DatabaseType.DWSQL, CliBool.True, DisplayName = "Init command with '--graphql.multiple-create.enabled true' for DWSQL database type")]
448+
[DataRow(DatabaseType.DWSQL, CliBool.False, DisplayName = "Init command with '--graphql.multiple-create.enabled false' for DWSQL database type")]
449+
[DataRow(DatabaseType.DWSQL, CliBool.None, DisplayName = "Init command without '--graphql.multiple-create.enabled' option for DWSQL database type")]
450+
public Task VerifyCorrectConfigGenerationWithMultipleMutationOptions(DatabaseType databaseType, CliBool isMultipleCreateEnabled)
451+
{
452+
InitOptions options;
453+
454+
if (databaseType is DatabaseType.CosmosDB_NoSQL)
455+
{
456+
// A schema file is added since its mandatory for CosmosDB_NoSQL
457+
((MockFileSystem)_fileSystem!).AddFile(TEST_SCHEMA_FILE, new MockFileData(""));
458+
459+
options = new(
460+
databaseType: databaseType,
461+
connectionString: "testconnectionstring",
462+
cosmosNoSqlDatabase: "testdb",
463+
cosmosNoSqlContainer: "testcontainer",
464+
graphQLSchemaPath: TEST_SCHEMA_FILE,
465+
setSessionContext: true,
466+
hostMode: HostMode.Development,
467+
corsOrigin: new List<string>() { "http://localhost:3000", "http://nolocalhost:80" },
468+
authenticationProvider: EasyAuthType.StaticWebApps.ToString(),
469+
restPath: "rest-api",
470+
config: TEST_RUNTIME_CONFIG_FILE,
471+
multipleCreateOperationEnabled: isMultipleCreateEnabled);
472+
}
473+
else
474+
{
475+
options = new(
476+
databaseType: databaseType,
477+
connectionString: "testconnectionstring",
478+
cosmosNoSqlDatabase: null,
479+
cosmosNoSqlContainer: null,
480+
graphQLSchemaPath: null,
481+
setSessionContext: true,
482+
hostMode: HostMode.Development,
483+
corsOrigin: new List<string>() { "http://localhost:3000", "http://nolocalhost:80" },
484+
authenticationProvider: EasyAuthType.StaticWebApps.ToString(),
485+
restPath: "rest-api",
486+
config: TEST_RUNTIME_CONFIG_FILE,
487+
multipleCreateOperationEnabled: isMultipleCreateEnabled);
488+
}
489+
490+
VerifySettings verifySettings = new();
491+
verifySettings.UseHashedParameters(databaseType, isMultipleCreateEnabled);
492+
return ExecuteVerifyTest(options, verifySettings);
493+
}
494+
412495
private Task ExecuteVerifyTest(InitOptions options, VerifySettings? settings = null)
413496
{
414497
Assert.IsTrue(TryCreateRuntimeConfig(options, _runtimeConfigLoader!, _fileSystem!, out RuntimeConfig? runtimeConfig));

src/Cli.Tests/ModuleInitializer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public static void Init()
3131
VerifierSettings.IgnoreMember<RuntimeOptions>(options => options.IsCachingEnabled);
3232
// Ignore the entity IsCachingEnabled as that's unimportant from a test standpoint.
3333
VerifierSettings.IgnoreMember<Entity>(entity => entity.IsCachingEnabled);
34+
// Ignore the entity IsLinkingEntity as that's unimportant from a test standpoint.
35+
VerifierSettings.IgnoreMember<Entity>(entity => entity.IsLinkingEntity);
3436
// Ignore the UserProvidedTtlOptions. They aren't serialized to our config file, enforced by EntityCacheOptionsConverter.
3537
VerifierSettings.IgnoreMember<EntityCacheOptions>(cacheOptions => cacheOptions.UserProvidedTtlOptions);
3638
// Ignore the IsRequestBodyStrict as that's unimportant from a test standpoint.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
DataSource: {
3+
DatabaseType: DWSQL,
4+
Options: {
5+
set-session-context: true
6+
}
7+
},
8+
Runtime: {
9+
Rest: {
10+
Enabled: true,
11+
Path: /rest-api,
12+
RequestBodyStrict: true
13+
},
14+
GraphQL: {
15+
Enabled: true,
16+
Path: /graphql,
17+
AllowIntrospection: true
18+
},
19+
Host: {
20+
Cors: {
21+
Origins: [
22+
http://localhost:3000,
23+
http://nolocalhost:80
24+
],
25+
AllowCredentials: false
26+
},
27+
Authentication: {
28+
Provider: StaticWebApps
29+
}
30+
}
31+
},
32+
Entities: []
33+
}

0 commit comments

Comments
 (0)