From 579545e55cee31583a390cae487b8b2b95c994b4 Mon Sep 17 00:00:00 2001 From: Geoff McElhanon Date: Fri, 16 Aug 2024 14:27:35 -0500 Subject: [PATCH] [ODS-6427] Support extensibility for change queries request authorization based on custom database views (#1120) --- ...edAuthorizationFilterDefinitionsFactory.cs | 139 +- .../ViewBasedAuthorizationFilterDefinition.cs | 52 +- .../Database/Querying/QueryBuilder.cs | 23 +- .../Querying/SqlBuilder_customizations.cs | 26 + .../CustomViewBasedAuthorizationStrategy.cs | 4 +- ...sQueryFactoryAuthorizationDecoratorBase.cs | 23 +- ...Test Suite.postman_collection.json.manual} | 1875 ++++++++++++----- 7 files changed, 1545 insertions(+), 597 deletions(-) rename Postman Test Suite/{Custom View-Based Authorization Test Suite.postman_collection.json.manual => Ed-Fi ODS-API Custom View-Based Authorization Test Suite.postman_collection.json.manual} (66%) diff --git a/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/CustomViewBased/CustomViewBasedAuthorizationFilterDefinitionsFactory.cs b/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/CustomViewBased/CustomViewBasedAuthorizationFilterDefinitionsFactory.cs index 0f354a9376..0b88a40d4b 100644 --- a/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/CustomViewBased/CustomViewBasedAuthorizationFilterDefinitionsFactory.cs +++ b/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/CustomViewBased/CustomViewBasedAuthorizationFilterDefinitionsFactory.cs @@ -4,10 +4,10 @@ // See the LICENSE and NOTICES files in the project root for more information. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using EdFi.Common.Extensions; -using EdFi.Ods.Api.Security.Authorization; using EdFi.Ods.Api.Security.AuthorizationStrategies.Relationships.Filters; using EdFi.Ods.Api.Security.Extensions; using EdFi.Ods.Common.Database.NamingConventions; @@ -15,43 +15,29 @@ using EdFi.Ods.Common.Exceptions; using EdFi.Ods.Common.Infrastructure.Filtering; using EdFi.Ods.Common.Models.Resource; -using EdFi.Ods.Common.Security; using EdFi.Ods.Common.Security.Authorization; using EdFi.Ods.Common.Security.Claims; -using NHibernate; -using NHibernate.Criterion; -using NHibernate.SqlCommand; namespace EdFi.Ods.Api.Security.AuthorizationStrategies.CustomViewBased; -// ------------------------------------------------------------------------------------------ -// TODO: ODS-6426, ODS-6427 - This file is a work-in-progress across multiple stories. -// ------------------------------------------------------------------------------------------ - public class CustomViewBasedAuthorizationFilterDefinitionsFactory : IAuthorizationFilterDefinitionsFactory { - // private readonly IDatabaseNamingConvention _databaseNamingConvention; - // private readonly AuthorizationContextDataFactory _authorizationContextDataFactory = new(); + private readonly IDatabaseNamingConvention _databaseNamingConvention; + + private const string TrackedChangesAlias = "c"; - private readonly IEducationOrganizationIdNamesProvider _educationOrganizationIdNamesProvider; - private readonly IApiClientContextProvider _apiClientContextProvider; private readonly IViewBasedSingleItemAuthorizationQuerySupport _viewBasedSingleItemAuthorizationQuerySupport; private readonly ICustomViewBasisEntityProvider _customViewBasisEntityProvider; + private readonly ConcurrentDictionary<(Resource resource, string viewName), string> _nonIdentifyingPropertiesTextByResourceAndView = new(); public CustomViewBasedAuthorizationFilterDefinitionsFactory( - // IDatabaseNamingConvention databaseNamingConvention, - IEducationOrganizationIdNamesProvider educationOrganizationIdNamesProvider, - IApiClientContextProvider apiClientContextProvider, + IDatabaseNamingConvention databaseNamingConvention, IViewBasedSingleItemAuthorizationQuerySupport viewBasedSingleItemAuthorizationQuerySupport, ICustomViewBasisEntityProvider customViewBasisEntityProvider) { - // _databaseNamingConvention = databaseNamingConvention; - _educationOrganizationIdNamesProvider = educationOrganizationIdNamesProvider; - _apiClientContextProvider = apiClientContextProvider; + _databaseNamingConvention = databaseNamingConvention; _viewBasedSingleItemAuthorizationQuerySupport = viewBasedSingleItemAuthorizationQuerySupport; _customViewBasisEntityProvider = customViewBasisEntityProvider; - - // _oldNamespaceQueryColumnExpression = $"{TrackedChangesAlias}.{databaseNamingConvention.ColumnName($"OldNamespace")}"; } public AuthorizationFilterDefinition CreateAuthorizationFilterDefinition(string filterName) @@ -115,18 +101,6 @@ private InstanceAuthorizationResult AuthorizeInstance( // whether the endpoint values are null or not. return InstanceAuthorizationResult.NotPerformed(); } - - // If the subject's endpoint name is an Education Organization Id, we can try to authenticate it here using claim values - if (_educationOrganizationIdNamesProvider.IsEducationOrganizationIdName(authorizationFilterContext.SubjectEndpointNames[i])) - { - // NOTE: Could consider caching the EdOrgToEdOrgId tuple table. - // If the EdOrgId values match, then we can report the filter as successfully authorized - if (_apiClientContextProvider.GetApiClientContext() - .EducationOrganizationIds.Contains((long) authorizationFilterContext.SubjectEndpointValues[i])) - { - return InstanceAuthorizationResult.Success(); - } - } } return InstanceAuthorizationResult.NotPerformed(); @@ -140,45 +114,64 @@ private void ApplyTrackedChangesAuthorizationCriteria( QueryBuilder queryBuilder, bool useOuterJoins) { - throw new NotSupportedException(); - - // if (filterContext.ClaimParameterValues.Length == 1) - // { - // if (filterContext.SubjectEndpointName == "Namespace") - // { - // queryBuilder.WhereLike($"{_oldNamespaceQueryColumnExpression}", filterContext.ClaimParameterValues.Single()); - // } - // else - // { - // queryBuilder.WhereLike( - // $"{TrackedChangesAlias}.{_databaseNamingConvention.ColumnName($"Old{filterContext.SubjectEndpointName}")}", - // filterContext.ClaimParameterValues.Single()); - // } - // } - // else if (filterContext.ClaimParameterValues.Length > 1) - // { - // queryBuilder.Where( - // q => - // { - // if (filterContext.SubjectEndpointName == "Namespace") - // { - // filterContext.ClaimParameterValues.ForEach(ns => q.OrWhereLike(_oldNamespaceQueryColumnExpression, ns)); - // } - // else - // { - // filterContext.ClaimParameterValues.ForEach( - // ns => q.OrWhereLike( - // $"{TrackedChangesAlias}.{_databaseNamingConvention.ColumnName($"Old{filterContext.SubjectEndpointName}")}", - // ns)); - // } - // - // return q; - // }); - // } - // else - // { - // // This should never happen - // throw new SecurityAuthorizationException(SecurityAuthorizationException.DefaultTechnicalProblemDetail, "No namespaces found in claims."); - // } + if (filterDefinition is not ViewBasedAuthorizationFilterDefinition viewBasedFilterDefinition) + { + throw new Exception($"Expected a view-based filter definition of type '{nameof(ViewBasedAuthorizationFilterDefinition)}'."); + } + + string viewName = viewBasedFilterDefinition.ViewName; + + string[] trackedChangesPropertyNames = resource.Entity.IsDerived + ? filterContext.SubjectEndpointNames.Select(GetBasePropertyNameForSubjectEndpointName).ToArray() + : filterContext.SubjectEndpointNames; + + if (useOuterJoins) + { + throw new InvalidOperationException("Outer joins are not used with custom view-based authorizations."); + } + + // Verify that all the tracked changes property names are identifying (a requirement for tracked change queries) + string nonIdentifyPropertyNames = _nonIdentifyingPropertiesTextByResourceAndView.GetOrAdd( + (resource, viewBasedFilterDefinition.ViewName), + (x, propertyNames) => + { + return string.Join( + "', '", + propertyNames.Where( + tcpn => !x.resource.Entity.Identifier.Properties.Any(p => p.PropertyName.EqualsIgnoreCase(tcpn)))); + }, + trackedChangesPropertyNames); + + if (nonIdentifyPropertyNames.Length > 0) + { + throw new SecurityConfigurationException( + SecurityConfigurationException.DefaultDetail, + $"Non-identifying properties ('{nonIdentifyPropertyNames}') were found to be used for the custom view-based authorization strategy, but this is not supported by Change Queries which only tracks deleted/changed values of identifying properties. Should a different authorization strategy be used?"); + } + + queryBuilder.Join( + $"auth.{viewName} AS rba{filterIndex}", + j => + { + for (int i = 0; i < trackedChangesPropertyNames.Length; i++) + { + j.On( + $"{TrackedChangesAlias}.{_databaseNamingConvention.ColumnName($"Old{trackedChangesPropertyNames[i]}")}", + $"rba{filterIndex}.{_databaseNamingConvention.ColumnName(viewBasedFilterDefinition.ViewTargetEndpointNames[i])}"); + } + + return j; + }); + + string GetBasePropertyNameForSubjectEndpointName(string filterContextSubjectEndpointName) + { + if (!resource.Entity.PropertyByName.TryGetValue(filterContextSubjectEndpointName, out var entityProperty)) + { + throw new Exception( + $"Unable to find property '{filterContextSubjectEndpointName}' on entity '{resource.Entity.FullName}'."); + } + + return entityProperty.BaseProperty.PropertyName; + } } } diff --git a/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/Relationships/Filters/ViewBasedAuthorizationFilterDefinition.cs b/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/Relationships/Filters/ViewBasedAuthorizationFilterDefinition.cs index 1436c28b8e..70c2dad705 100644 --- a/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/Relationships/Filters/ViewBasedAuthorizationFilterDefinition.cs +++ b/Application/EdFi.Ods.Api/Security/AuthorizationStrategies/Relationships/Filters/ViewBasedAuthorizationFilterDefinition.cs @@ -12,10 +12,6 @@ using EdFi.Ods.Common.Security.Authorization; using EdFi.Ods.Common.Security.Claims; -// ------------------------------------------------------------------------------------------ -// TODO: ODS-6426, ODS-6427 - This file is a work-in-progress across multiple stories. -// ------------------------------------------------------------------------------------------ - namespace EdFi.Ods.Api.Security.AuthorizationStrategies.Relationships.Filters { public class ViewBasedAuthorizationFilterDefinition : AuthorizationFilterDefinition @@ -69,8 +65,8 @@ public ViewBasedAuthorizationFilterDefinition( authorizeInstance) { ViewName = viewName; - ViewSourceEndpointName = viewSourceEndpointName; - ViewTargetEndpointName = viewTargetEndpointName; + ViewSourceEndpointNames = [viewSourceEndpointName]; + ViewTargetEndpointNames = [viewTargetEndpointName]; ViewBasedSingleItemAuthorizationQuerySupport = viewBasedSingleItemAuthorizationQuerySupport; } @@ -87,26 +83,19 @@ public ViewBasedAuthorizationFilterDefinition( public ViewBasedAuthorizationFilterDefinition( string filterName, string viewName, - // string viewSourceEndpointName, string[] viewTargetEndpointNames, Action trackedChangesCriteriaApplicator, Func authorizeInstance, - IViewBasedSingleItemAuthorizationQuerySupport viewBasedSingleItemAuthorizationQuerySupport) //, - // IMultiValueRestrictions multiValueRestrictions) + IViewBasedSingleItemAuthorizationQuerySupport viewBasedSingleItemAuthorizationQuerySupport) : base( filterName, $@"{{currentAlias}}.{{subjectEndpointName}} IN ( SELECT {{newAlias1}}.{viewTargetEndpointNames[0]} // TODO: Fix HQL FROM {GetFullNameForView($"auth_{viewName}")} {{newAlias1}} )", - //WHERE {{newAlias1}}.{viewSourceEndpointName} IN (:{RelationshipAuthorizationConventions.ClaimsParameterName}))", (criteria, @where, subjectEndpointNames, parameters, joinType, authorizationStrategy) => criteria.ApplyCustomViewJoinFilter( - // multiValueRestrictions, - // @where, - // parameters, viewName, subjectEndpointNames, - // viewSourceEndpointName, viewTargetEndpointNames, joinType, Guid.NewGuid().ToString("N"), @@ -115,17 +104,44 @@ public ViewBasedAuthorizationFilterDefinition( authorizeInstance) { ViewName = viewName; - // ViewSourceEndpointName = viewSourceEndpointName; ViewTargetEndpointNames = viewTargetEndpointNames; ViewBasedSingleItemAuthorizationQuerySupport = viewBasedSingleItemAuthorizationQuerySupport; } public string ViewName { get; } - - public string ViewSourceEndpointName { get; } - public string ViewTargetEndpointName { get; } + public string[] ViewSourceEndpointNames { get; } public string[] ViewTargetEndpointNames { get; } + // Single-value property retained for backwards compatibility with existing use of single-column joins + public string ViewSourceEndpointName + { + get + { + return ViewSourceEndpointNames?.Length switch + { + 0 => null, + 1 => ViewSourceEndpointNames[0], + _ => throw new InvalidOperationException( + "Multiple view source endpoint names were found in the filter definition when exactly one was expected.") + }; + } + } + + // Single-value property retained for backwards compatibility with existing use of single-column joins + public string ViewTargetEndpointName + { + get + { + return ViewTargetEndpointNames?.Length switch + { + 0 => null, + 1 => ViewTargetEndpointNames[0], + _ => throw new InvalidOperationException( + "Multiple view target endpoint names were found in the filter definition when exactly one was expected.") + }; + } + } + public IViewBasedSingleItemAuthorizationQuerySupport ViewBasedSingleItemAuthorizationQuerySupport { get; set; } private static string GetFullNameForView(string viewName) diff --git a/Application/EdFi.Ods.Common/Database/Querying/QueryBuilder.cs b/Application/EdFi.Ods.Common/Database/Querying/QueryBuilder.cs index f2749e780e..6b88917fb8 100644 --- a/Application/EdFi.Ods.Common/Database/Querying/QueryBuilder.cs +++ b/Application/EdFi.Ods.Common/Database/Querying/QueryBuilder.cs @@ -131,16 +131,19 @@ public QueryBuilder Where(Func nestedWhereApplicator return this; } - var template = childScopeSqlBuilder.AddTemplate( - "/**where**/", - childScope.Parameters.Any() - ? new DynamicParameters(childScope.Parameters) - : null); - - // Wrap the WHERE clause directly - _sqlBuilder.Where($"({template.RawSql.Replace("WHERE ", string.Empty)})", template.Parameters); + if (childScopeSqlBuilder.HasWhereClause()) + { + var template = childScopeSqlBuilder.AddTemplate( + "/**where**/", + childScope.Parameters.Any() + ? new DynamicParameters(childScope.Parameters) + : null); + + // Wrap the WHERE clause directly + _sqlBuilder.Where($"({template.RawSql.Replace("WHERE ", string.Empty)})", template.Parameters); + } - // Incorporate the JOINs into this builder + // Incorporate any JOINs added into this builder _sqlBuilder.CopyDataFrom(childScopeSqlBuilder, "innerjoin", "leftjoin", "rightjoin", "join"); return this; @@ -325,7 +328,7 @@ public QueryBuilder Distinct() return this; } - + public QueryBuilder LimitOffset(int limit, int offset = 0) { // Apply paging diff --git a/Application/EdFi.Ods.Common/Database/Querying/SqlBuilder_customizations.cs b/Application/EdFi.Ods.Common/Database/Querying/SqlBuilder_customizations.cs index a90b3cf121..ff7e5404e1 100644 --- a/Application/EdFi.Ods.Common/Database/Querying/SqlBuilder_customizations.cs +++ b/Application/EdFi.Ods.Common/Database/Querying/SqlBuilder_customizations.cs @@ -143,5 +143,31 @@ public bool IsEmpty() { return _data.Count == 0; } + + public bool HasWhereClause() + { + return HasClause(ClauseKey.Where); + } + + private bool HasClause(string clausekey) + { + return _data.Any(kvp => kvp.Key == clausekey); + } + } + + public static class ClauseKey + { + public static string Intersect = "intersect"; + public static string InnerJoin = "innerjoin"; + public static string LeftJoin = "leftjoin"; + public static string RightJoin = "rightjoin"; + public static string Where = "where"; + public static string OrderBy = "orderby"; + public static string Select = "select"; + public static string Parameters = "--parameters"; + public static string Join = "join"; + public static string GroupBy = "groupby"; + public static string Having = "having"; + public static string Set = "set"; } } diff --git a/Application/EdFi.Ods.Common/Security/Authorization/CustomViewBasedAuthorizationStrategy.cs b/Application/EdFi.Ods.Common/Security/Authorization/CustomViewBasedAuthorizationStrategy.cs index 24e13f732b..7e6fd61c75 100644 --- a/Application/EdFi.Ods.Common/Security/Authorization/CustomViewBasedAuthorizationStrategy.cs +++ b/Application/EdFi.Ods.Common/Security/Authorization/CustomViewBasedAuthorizationStrategy.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using EdFi.Ods.Common.Exceptions; using EdFi.Ods.Common.Models; using EdFi.Ods.Common.Models.Domain; using EdFi.Ods.Common.Security.Claims; @@ -83,7 +84,8 @@ List GetAuthorizationSubjectEndpointNames() continue; } - throw new Exception( + throw new SecurityConfigurationException( + SecurityConfigurationException.DefaultDetail, $"Unable to find a property on the authorization subject entity type '{subjectEntity.Name}' corresponding to the '{basisProperty.PropertyName}' property on the custom authorization view's basis entity type '{_basisEntity.Name}' in order to perform authorization. Should a different authorization strategy be used?"); } diff --git a/Application/EdFi.Ods.Features/ChangeQueries/Repositories/Authorization/TrackedChangesQueryFactoryAuthorizationDecoratorBase.cs b/Application/EdFi.Ods.Features/ChangeQueries/Repositories/Authorization/TrackedChangesQueryFactoryAuthorizationDecoratorBase.cs index df3ae3ad72..c4284b7d18 100644 --- a/Application/EdFi.Ods.Features/ChangeQueries/Repositories/Authorization/TrackedChangesQueryFactoryAuthorizationDecoratorBase.cs +++ b/Application/EdFi.Ods.Features/ChangeQueries/Repositories/Authorization/TrackedChangesQueryFactoryAuthorizationDecoratorBase.cs @@ -88,7 +88,7 @@ protected void ApplyAuthorizationFilters(Resource resource, QueryBuilder queryBu var unsupportedAuthorizationFilters = new HashSet(); // If there are multiple authorization strategies with views, we must use left outer joins and null/not null checks - var joinType = DetermineJoinType(); + var relationshipBasedAuthViewJoinType = DetermineRelationshipBasedAuthViewJoinType(); var filterIndex = 0; @@ -97,10 +97,10 @@ protected void ApplyAuthorizationFilters(Resource resource, QueryBuilder queryBu return; - JoinType DetermineJoinType() + JoinType DetermineRelationshipBasedAuthViewJoinType() { - var countOfAuthorizationFiltersWithViewBasedFilters = authorizationFiltering.Count( - af => af.Filters.Select( + var countOfRelationshipBasedAuthorizationFilters = authorizationFiltering.Count( + af => af.Operator == FilterOperator.Or && af.Filters.Select( afd => { if (_authorizationFilterDefinitionProvider.TryGetAuthorizationFilterDefinition( @@ -118,7 +118,7 @@ JoinType DetermineJoinType() .OfType() .Any()); - return countOfAuthorizationFiltersWithViewBasedFilters > 1 + return countOfRelationshipBasedAuthorizationFilters > 1 ? JoinType.LeftOuterJoin : JoinType.InnerJoin; } @@ -135,7 +135,7 @@ void ApplyAuthorizationStrategiesCombinedWithAndLogic() { foreach (var andStrategy in andStrategies) { - if (!TryApplyFilters(nestedAndQueryBuilder, andStrategy.Filters)) + if (!TryApplyFilters(nestedAndQueryBuilder, andStrategy.Filters, false)) { // All filters for AND strategies must be applied, and if not, this is an error condition throw new Exception( @@ -162,7 +162,7 @@ void ApplyAuthorizationStrategiesCombinedWithOrLogic() { foreach (var orStrategy in orStrategies) { - if (TryApplyFilters(nestedOrQueryBuilder, orStrategy.Filters)) + if (TryApplyFilters(nestedOrQueryBuilder, orStrategy.Filters, relationshipBasedAuthViewJoinType != JoinType.InnerJoin)) { orFiltersApplied = true; } @@ -180,7 +180,7 @@ void ApplyAuthorizationStrategiesCombinedWithOrLogic() } } - bool TryApplyFilters(QueryBuilder nestedQueryBuilder, IReadOnlyList filterContexts) + bool TryApplyFilters(QueryBuilder nestedQueryBuilder, IReadOnlyList filterContexts, bool useOuterJoins) { bool allFiltersCanBeApplied = true; @@ -211,11 +211,6 @@ bool TryApplyFilters(QueryBuilder nestedQueryBuilder, IReadOnlyList - // { - // { filterContext.ClaimParameterName, filterContext.ClaimParameterValues } - // }; - // Apply the authorization strategy filter applicator( filterDefinition, @@ -223,7 +218,7 @@ bool TryApplyFilters(QueryBuilder nestedQueryBuilder, IReadOnlyList {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return 1 deleted item.\", () => {\r", + " pm.expect(items.length).to.equal(1);\r", + "});\r", + "\r", + "const item = items[0];\r", + "\r", + "pm.test(\"Should return an entry with the key values of the item previously added and deleted.\", () => {\r", + " pm.expect(item.keyValues).to.deep.equal({\r", + " \"studentUniqueId\": \"ABC123\",\r", + " \"educationOrganizationId\": 255901,\r", + " \"programEducationOrganizationId\": 255901,\r", + " \"programName\": \"Gifted and Talented\",\r", + " \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Gifted and Talented\",\r", + " \"beginDate\": \"2021-08-30\",\r", + " });\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentProgramAssociations/deletes?MinChangeVersion={{known:changeVersion:minimum}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentProgramAssociations", + "deletes" + ], + "query": [ + { + "key": "MinChangeVersion", + "value": "{{known:changeVersion:minimum}}" + } + ] + } + }, + "response": [] } ] }, @@ -854,7 +947,41 @@ "item": [ { "name": "Setup", - "item": [] + "item": [ + { + "name": "Get Available Changes", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const item = pm.response.json();\r", + "\r", + "pm.environment.set(\"known:changeVersion:minimum\", item.newestChangeVersion + 1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/changeQueries/v1/availableChangeVersions", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "changeQueries", + "v1", + "availableChangeVersions" + ] + } + }, + "response": [] + } + ] }, { "name": "Student Special Ed Program Eligibility Lifecycle", @@ -1167,21 +1294,9 @@ } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"consentToEvaluationReceivedDate\": \"2024-08-02\",\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"programReference\": {\r\n \"educationOrganizationId\": 255901,\r\n \"programName\": \"Bilingual\",\r\n \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Bilingual\"\r\n },\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"ideaPartDescriptor\": \"uri://ed-fi.org/IDEAPartDescriptor#IDEA Part B\"\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentSpecialEducationProgramEligibilityAssociations/{{known:studentSpecialEducationProgramEligibilityAssociation:id}}", "host": [ @@ -1219,21 +1334,9 @@ } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"consentToEvaluationReceivedDate\": \"2024-08-02\",\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"programReference\": {\r\n \"educationOrganizationId\": 255901,\r\n \"programName\": \"Bilingual\",\r\n \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Bilingual\"\r\n },\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"ideaPartDescriptor\": \"uri://ed-fi.org/IDEAPartDescriptor#IDEA Part B\"\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentSpecialEducationProgramEligibilityAssociations", "host": [ @@ -1439,21 +1542,9 @@ } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"consentToEvaluationReceivedDate\": \"2024-08-02\",\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"programReference\": {\r\n \"educationOrganizationId\": 255901,\r\n \"programName\": \"Bilingual\",\r\n \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Bilingual\"\r\n },\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"ideaPartDescriptor\": \"uri://ed-fi.org/IDEAPartDescriptor#IDEA Part B\"\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentSpecialEducationProgramEligibilityAssociations/{{known:studentSpecialEducationProgramEligibilityAssociation:id}}", "host": [ @@ -1491,21 +1582,9 @@ } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"consentToEvaluationReceivedDate\": \"2024-08-02\",\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"programReference\": {\r\n \"educationOrganizationId\": 255901,\r\n \"programName\": \"Bilingual\",\r\n \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Bilingual\"\r\n },\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"ideaPartDescriptor\": \"uri://ed-fi.org/IDEAPartDescriptor#IDEA Part B\"\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentSpecialEducationProgramEligibilityAssociations", "host": [ @@ -1711,6 +1790,65 @@ } }, "response": [] + }, + { + "name": "Get Deleted Special Ed Program Eligibility", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return 1 deleted item.\", () => {\r", + " pm.expect(items.length).to.equal(1);\r", + "});\r", + "\r", + "const item = items[0];\r", + "\r", + "pm.test(\"Should return an entry with the key values of the item previously added and deleted.\", () => {\r", + " pm.expect(item.keyValues).to.deep.equal({\r", + " \"consentToEvaluationReceivedDate\": \"2024-08-02\",\r", + " \"studentUniqueId\": \"ABC123\",\r", + " \"educationOrganizationId\": 255901,\r", + " \"programName\": \"Bilingual\",\r", + " \"programTypeDescriptor\": \"uri://ed-fi.org/ProgramTypeDescriptor#Bilingual\",\r", + " });\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentSpecialEducationProgramEligibilityAssociations/deletes?MinChangeVersion={{known:changeVersion:minimum}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentSpecialEducationProgramEligibilityAssociations", + "deletes" + ], + "query": [ + { + "key": "MinChangeVersion", + "value": "{{known:changeVersion:minimum}}" + } + ] + } + }, + "response": [] } ] }, @@ -1894,68 +2032,680 @@ "name": "Composite Key View-based Authorization", "item": [ { - "name": "Create Student Assessment (unaffiliated SchoolId, non ACT assessment)", - "event": [ + "name": "Setup", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 403\", () => {\r", - " pm.expect(pm.response.code).to.equal(403);\r", - "});\r", - "\r", - "pm.test(\"Detail indicates basic authorization message.\", () => {\r", - " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized.\");\r", - "})\r", - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 5\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [\r\n {\r\n \"assessmentItemReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"identificationCode\": \"0\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\",\r\n \"link\": {\r\n \"rel\": \"AssessmentItem\",\r\n \"href\": \"/ed-fi/assessmentItems/776f505ee30d4574976d51a581595ff6\"\r\n }\r\n },\r\n \"assessmentItemResultDescriptor\": \"uri://ed-fi.org/AssessmentItemResultDescriptor#Correct\",\r\n \"assessmentResponse\": \"A\",\r\n \"responseIndicatorDescriptor\": \"uri://ed-fi.org/ResponseIndicatorDescriptor#Nonscorable response\"\r\n }\r\n ],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", - "options": { - "raw": { - "language": "json" + "name": "Get Available Changes", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const item = pm.response.json();\r", + "\r", + "pm.environment.set(\"known:changeVersion:minimum\", item.newestChangeVersion + 1);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", - "host": [ - "{{ApiBaseUrl}}" ], - "path": [ - "data", - "v3", - "ed-fi", - "studentAssessments" - ] + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/changeQueries/v1/availableChangeVersions", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "changeQueries", + "v1", + "availableChangeVersions" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Create Student Assessment (affiliated SchoolId, non ACT assessment)", - "event": [ + "name": "Student Assessment Lifecyle", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 403\", () => {\r", - " pm.expect(pm.response.code).to.equal(403);\r", + "name": "Create Student Assessment (unaffiliated SchoolId, non ACT assessment)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 403\", () => {\r", + " pm.expect(pm.response.code).to.equal(403);\r", + "});\r", + "\r", + "pm.test(\"Detail indicates basic authorization message.\", () => {\r", + " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized.\");\r", + "})\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 5\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [\r\n {\r\n \"assessmentItemReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"identificationCode\": \"0\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\",\r\n \"link\": {\r\n \"rel\": \"AssessmentItem\",\r\n \"href\": \"/ed-fi/assessmentItems/776f505ee30d4574976d51a581595ff6\"\r\n }\r\n },\r\n \"assessmentItemResultDescriptor\": \"uri://ed-fi.org/AssessmentItemResultDescriptor#Correct\",\r\n \"assessmentResponse\": \"A\",\r\n \"responseIndicatorDescriptor\": \"uri://ed-fi.org/ResponseIndicatorDescriptor#Nonscorable response\"\r\n }\r\n ],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments" + ] + } + }, + "response": [] + }, + { + "name": "Create Student Assessment (affiliated SchoolId, non ACT assessment)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 403\", () => {\r", + " pm.expect(pm.response.code).to.equal(403);\r", + "});\r", + "\r", + "pm.test(\"Detail indicates basic authorization message.\", () => {\r", + " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized.\");\r", + "})\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 255901001\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [\r\n {\r\n \"assessmentItemReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"identificationCode\": \"0\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\",\r\n \"link\": {\r\n \"rel\": \"AssessmentItem\",\r\n \"href\": \"/ed-fi/assessmentItems/776f505ee30d4574976d51a581595ff6\"\r\n }\r\n },\r\n \"assessmentItemResultDescriptor\": \"uri://ed-fi.org/AssessmentItemResultDescriptor#Correct\",\r\n \"assessmentResponse\": \"A\",\r\n \"responseIndicatorDescriptor\": \"uri://ed-fi.org/ResponseIndicatorDescriptor#Nonscorable response\"\r\n }\r\n ],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments" + ] + } + }, + "response": [] + }, + { + "name": "Get Student Assessments", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return no items.\", () => {\r", + " pm.expect(items.length).to.equal(0);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments?Limit=500", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments" + ], + "query": [ + { + "key": "Limit", + "value": "500" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Student Assessment (affiliated SchoolId, ACT assessment)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 201\", () => {\r", + " pm.expect(pm.response.code).to.equal(201);\r", + "});\r", + "\r", + "pm.environment.set('known:studentAssessment:id', pm.response.headers.one('Location').value.split(\"/\").pop());" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 255901001\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"ACT English\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments" + ] + } + }, + "response": [] + }, + { + "name": "Get Student Assessments", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"At least 1 item was returned.\", () => {\r", + " pm.expect(items.length).to.be.greaterThan(0);\r", + "});\r", + "\r", + "pm.test(\"All items have identifiers starting with ACT.\", () => {\r", + " // Iterate through all items to check the assessmentIdentifier\r", + " const allStartWithACT = items.every(item => {\r", + " return item.assessmentReference && \r", + " item.assessmentReference.assessmentIdentifier &&\r", + " item.assessmentReference.assessmentIdentifier.startsWith(\"ACT\");\r", + " });\r", + " \r", + " // Assert that all items pass the condition\r", + " pm.expect(allStartWithACT).to.be.true;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments?Limit=500", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments" + ], + "query": [ + { + "key": "Limit", + "value": "500" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Student Assessment By id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments/{{known:studentAssessment:id}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments", + "{{known:studentAssessment:id}}" + ] + } + }, + "response": [] + }, + { + "name": "Delete Student Assessment", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 204\", () => {\r", + " pm.expect(pm.response.code).to.equal(204);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments/{{known:studentAssessment:id}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments", + "{{known:studentAssessment:id}}" + ] + } + }, + "response": [] + }, + { + "name": "Get Deleted Student Assessment", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return 1 deleted item.\", () => {\r", + " pm.expect(items.length).to.equal(1);\r", + "});\r", + "\r", + "const item = items[0];\r", + "\r", + "pm.test(\"Should return an entry with the key values of the item previously added and deleted.\", () => {\r", + " pm.expect(item.keyValues).to.deep.equal({\r", + " \"studentUniqueId\": \"ABC123\",\r", + " \"assessmentIdentifier\": \"ACT English\",\r", + " \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\",\r", + " \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\"\r", + " });\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments/deletes?MinChangeVersion={{known:changeVersion:minimum}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentAssessments", + "deletes" + ], + "query": [ + { + "key": "MinChangeVersion", + "value": "{{known:changeVersion:minimum}}" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Teardown", + "item": [ + { + "name": "Clean up Environment Variables", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// Remove all environment variables that start with \"known:\" or \"supplied:\"\r", + "_.chain(_.keys(pm.environment.toObject()))\r", + " .filter(x => _.startsWith(x, 'known:') || _.startsWith(x, 'supplied:'))\r", + " .each(k => pm.environment.unset(k)).value();" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}", + "host": [ + "{{ApiBaseUrl}}" + ] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "Custom View-based on Optional Property", + "item": [ + { + "name": "Get Student Transportations", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return at least 1 item.\", () => {\r", + " pm.expect(items.length).to.be.greaterThan(0);\r", + "});\r", + "\r", + "pm.test(\"All items have transportation types containing the term 'Bus'.\", () => {\r", + " // Iterate through all items to check the assessmentIdentifier\r", + " const allContainBus = items.every(item => {\r", + " return item.transportationTypeDescriptor.indexOf(\"Bus\") >= 0;\r", + " });\r", + " \r", + " // Assert that all items pass the condition\r", + " pm.expect(allContainBus).to.be.true;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations?totalCount=true", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentTransportations" + ], + "query": [ + { + "key": "totalCount", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Student Transportations (with inaccesible transportation type)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 403\", () => {\r", + " pm.expect(pm.response.code).to.equal(403);\r", + "});\r", + "\r", + "pm.test(\"Detail indicates basic authorization message.\", () => {\r", + " pm.expect(pm.response.json().detail).to.match(/^Access to the requested data could not be authorized./);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"transportationTypeDescriptor\": \"uri://ed-fi.org/TransportationTypeDescriptor#General Public Transportation\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentTransportations" + ] + } + }, + "response": [] + }, + { + "name": "Update Student Transportations (with null transportation type)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 403\", () => {\r", + " pm.expect(pm.response.code).to.equal(403);\r", + "});\r", + "\r", + "pm.test(\"Detail indicates basic authorization message.\", () => {\r", + " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized. The 'TransportationTypeDescriptor' value is required for authorization purposes.\");\r", + "});\r", + "\r", + "pm.test(\"Type indicates an element is required.\", () => {\r", + " pm.expect(pm.response.json().type).to.equal(\"urn:ed-fi:api:security:authorization:custom-view:access-denied:element-required\");\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentTransportations" + ] + } + }, + "response": [] + }, + { + "name": "Update Student Transportations (with accesible transportation type)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", "});\r", "\r", - "pm.test(\"Detail indicates basic authorization message.\", () => {\r", - " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized.\");\r", - "})\r", - "" + "pm.environment.set('known:studentTransportation:id', pm.response.headers.one('Location').value.split(\"/\").pop());" ], "type": "text/javascript", "packages": {} @@ -1967,7 +2717,7 @@ "header": [], "body": { "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 255901001\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [\r\n {\r\n \"assessmentItemReference\": {\r\n \"assessmentIdentifier\": \"01774fa3-06f1-47fe-8801-c8b1e65057f2\",\r\n \"identificationCode\": \"0\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\",\r\n \"link\": {\r\n \"rel\": \"AssessmentItem\",\r\n \"href\": \"/ed-fi/assessmentItems/776f505ee30d4574976d51a581595ff6\"\r\n }\r\n },\r\n \"assessmentItemResultDescriptor\": \"uri://ed-fi.org/AssessmentItemResultDescriptor#Correct\",\r\n \"assessmentResponse\": \"A\",\r\n \"responseIndicatorDescriptor\": \"uri://ed-fi.org/ResponseIndicatorDescriptor#Nonscorable response\"\r\n }\r\n ],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", + "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"transportationTypeDescriptor\": \"uri://ed-fi.org/TransportationTypeDescriptor#Special Needs Bus\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", "options": { "raw": { "language": "json" @@ -1975,7 +2725,7 @@ } }, "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", "host": [ "{{ApiBaseUrl}}" ], @@ -1983,14 +2733,14 @@ "data", "v3", "ed-fi", - "studentAssessments" + "studentTransportations" ] } }, "response": [] }, { - "name": "Get Student Assessments", + "name": "Get Student Transportation By id", "event": [ { "listen": "test", @@ -2000,10 +2750,10 @@ " pm.expect(pm.response.code).to.equal(200);\r", "});\r", "\r", - "const items = pm.response.json();\r", + "const item = pm.response.json();\r", "\r", - "pm.test(\"Should return no items.\", () => {\r", - " pm.expect(items.length).to.equal(0);\r", + "pm.test(\"Item returned should reflect changed transportationTypeDescriptor.\", () => {\r", + " pm.expect(item.transportationTypeDescriptor).to.contain(\"Special Needs Bus\");\r", "});\r", "" ], @@ -2012,23 +2762,62 @@ } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations/{{known:studentTransportation:id}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "studentTransportations", + "{{known:studentTransportation:id}}" + ] + } + }, + "response": [] + }, + { + "name": "Get Deleted Student Transportations", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 500\", () => {\r", + " pm.expect(pm.response.code).to.equal(500);\r", + "});\r", + "\r", + "const item = pm.response.json();\r", + "\r", + "pm.test(\"Detail should indicate a security configuration error.\", () => {\r", + " pm.expect(item).to.deep.contain({\r", + " \"detail\": \"A security configuration problem was detected. The request cannot be authorized.\",\r", + " \"type\": \"urn:ed-fi:api:system:configuration:security\",\r", + " \"title\": \"Security Configuration Error\",\r", + " \"status\": 500,\r", + " });\r", + "});\r", + "\r", + "pm.test(\"Errors should contain a message indicating only identifying properties can be used to authorize access to the deletes.\", () => {\r", + " pm.expect(item.errors).to.contain(\"Non-identifying properties ('TransportationTypeDescriptorId') were found to be used for the custom view-based authorization strategy, but this is not supported by Change Queries which only tracks deleted/changed values of identifying properties. Should a different authorization strategy be used?\");\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} } - }, + } + ], + "request": { + "method": "GET", + "header": [], "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments?Limit=500", + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations/deletes", "host": [ "{{ApiBaseUrl}}" ], @@ -2036,288 +2825,457 @@ "data", "v3", "ed-fi", - "studentAssessments" + "studentTransportations", + "deletes" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Custom View-based on EdOrgId", + "item": [ + { + "name": "Setup", + "item": [ + { + "name": "Get Available Changes", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const item = pm.response.json();\r", + "\r", + "pm.environment.set(\"known:changeVersion:minimum\", item.newestChangeVersion + 1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/changeQueries/v1/availableChangeVersions", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "changeQueries", + "v1", + "availableChangeVersions" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Accountability Rating Lifecycle", + "item": [ + { + "name": "Get Accountability Ratings", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return at least 1 item.\", () => {\r", + " pm.expect(items.length).to.be.greaterThan(0);\r", + "})\r", + "\r", + "pm.test(\"Should NOT return an accountability rating for the Local Education Agency\", () => {\r", + " // Get the response JSON array\r", + " const jsonData = pm.response.json();\r", + "\r", + " // Use the array.every() method to ensure no item contains the value 255901\r", + " const allIdsAreValid = jsonData.every(item => {\r", + " return item.educationOrganizationReference.educationOrganizationId !== 255901;\r", + " });\r", + "\r", + " // Assert that the condition is true\r", + " pm.expect(allIdsAreValid).to.be.true;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings" + ] + } + }, + "response": [] + }, + { + "name": "Create Accountability Rating (non-accessible EdOrg)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 403\", () => {\r", + " pm.expect(pm.response.code).to.equal(403);\r", + "});\r", + "\r", + "pm.test(\"Detail indicates basic authorization message.\", () => {\r", + " pm.expect(pm.response.json().detail).to.match(/^Access to the requested data could not be authorized./);\r", + "});\r", + "\r", + "pm.test(\"Errors indicate access cannot be authorized based on the EducationOrganizationId value.\", () => {\r", + " pm.expect(pm.response.json().errors).to.contain(\"The caller is not authorized to perform the requested operation on the item based on the proposed value of the 'EducationOrganizationId' property of the item.\");\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"ratingTitle\": \"Test Rating Title\",\r\n \"rating\": \"Test Rating\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings" + ] + } + }, + "response": [] + }, + { + "name": "Create Accountability Rating (accessible EdOrg)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 201\", () => {\r", + " pm.expect(pm.response.code).to.equal(201);\r", + "});\r", + "\r", + "pm.environment.set('known:accountabilityRating:id', pm.response.headers.one('Location').value.split(\"/\").pop());" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 6000203\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"ratingTitle\": \"Test Rating Title\",\r\n \"rating\": \"Test Rating\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings" + ] + } + }, + "response": [] + }, + { + "name": "Update Accountability Rating", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } ], - "query": [ - { - "key": "Limit", - "value": "500" + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 6000203\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"ratingTitle\": \"Test Rating Title\",\r\n \"rating\": \"Test Rating UPDATED\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings" + ] } - ] - } - }, - "response": [] - }, - { - "name": "Create Student Assessment (affiliated SchoolId, ACT assessment)", - "event": [ + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 201\", () => {\r", - " pm.expect(pm.response.code).to.equal(201);\r", - "});\r", - "\r", - "pm.environment.set('known:studentAssessment:id', pm.response.headers.one('Location').value.split(\"/\").pop());" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"ABC123\"\r\n },\r\n \"reportedSchoolReference\": {\r\n \"schoolId\": 255901001\r\n },\r\n \"assessmentReference\": {\r\n \"assessmentIdentifier\": \"ACT English\",\r\n \"namespace\": \"uri://ed-fi.org/Assessment/Assessment.xml\"\r\n },\r\n \"schoolYearTypeReference\": {\r\n \"schoolYear\": 2022\r\n },\r\n \"studentAssessmentIdentifier\": \"/Qhqqe/gI4p3RguP68ZEDArGHM64FKnCg/RLHG8c\",\r\n \"administrationDate\": \"2021-09-28T15:00:00Z\",\r\n \"administrationEnvironmentDescriptor\": \"uri://ed-fi.org/AdministrationEnvironmentDescriptor#Testing Center\",\r\n \"administrationLanguageDescriptor\": \"uri://ed-fi.org/LanguageDescriptor#eng\",\r\n \"retestIndicatorDescriptor\": \"uri://ed-fi.org/RetestIndicatorDescriptor#Primary Administration\",\r\n \"whenAssessedGradeLevelDescriptor\": \"uri://ed-fi.org/GradeLevelDescriptor#Third grade\",\r\n \"accommodations\": [],\r\n \"items\": [],\r\n \"performanceLevels\": [],\r\n \"scoreResults\": [\r\n {\r\n \"assessmentReportingMethodDescriptor\": \"uri://ed-fi.org/AssessmentReportingMethodDescriptor#Raw score\",\r\n \"result\": \"3\",\r\n \"resultDatatypeTypeDescriptor\": \"uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer\"\r\n }\r\n ],\r\n \"studentObjectiveAssessments\": []\r\n }", - "options": { - "raw": { - "language": "json" + "name": "Get Accountability Rating By Id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const item = pm.response.json();\r", + "\r", + "pm.test(\"Should return the accountability rating with the updated rating value\", () => {\r", + " // Assert that the condition is true\r", + " pm.expect(item.rating).to.equal(\"Test Rating UPDATED\");\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments", - "host": [ - "{{ApiBaseUrl}}" ], - "path": [ - "data", - "v3", - "ed-fi", - "studentAssessments" - ] - } - }, - "response": [] - }, - { - "name": "Get Student Assessments", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 200\", () => {\r", - " pm.expect(pm.response.code).to.equal(200);\r", - "});\r", - "\r", - "const items = pm.response.json();\r", - "\r", - "pm.test(\"At least 1 item was returned.\", () => {\r", - " pm.expect(items.length).to.be.greaterThan(0);\r", - "});\r", - "\r", - "pm.test(\"All items have identifiers starting with ACT.\", () => {\r", - " // Iterate through all items to check the assessmentIdentifier\r", - " const allStartWithACT = items.every(item => {\r", - " return item.assessmentReference && \r", - " item.assessmentReference.assessmentIdentifier &&\r", - " item.assessmentReference.assessmentIdentifier.startsWith(\"ACT\");\r", - " });\r", - " \r", - " // Assert that all items pass the condition\r", - " pm.expect(allStartWithACT).to.be.true;\r", - "});\r", - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings/{{known:accountabilityRating:id}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings", + "{{known:accountabilityRating:id}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments?Limit=500", - "host": [ - "{{ApiBaseUrl}}" - ], - "path": [ - "data", - "v3", - "ed-fi", - "studentAssessments" - ], - "query": [ + { + "name": "Delete Accountability Ratings", + "event": [ { - "key": "Limit", - "value": "500" + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 204\", () => {\r", + " pm.expect(pm.response.code).to.equal(204);\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } } - ] - } - }, - "response": [] - }, - { - "name": "Get Student Assessment By id", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 200\", () => {\r", - " pm.expect(pm.response.code).to.equal(200);\r", - "});\r", - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings/{{known:accountabilityRating:id}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings", + "{{known:accountabilityRating:id}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments/{{known:studentAssessment:id}}", - "host": [ - "{{ApiBaseUrl}}" - ], - "path": [ - "data", - "v3", - "ed-fi", - "studentAssessments", - "{{known:studentAssessment:id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Student Assessment", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 204\", () => {\r", - " pm.expect(pm.response.code).to.equal(204);\r", - "});\r", - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "Get Deleted Accountability Ratings", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", () => {\r", + " pm.expect(pm.response.code).to.equal(200);\r", + "});\r", + "\r", + "const items = pm.response.json();\r", + "\r", + "pm.test(\"Should return 1 deleted item.\", () => {\r", + " pm.expect(items.length).to.equal(1);\r", + "});\r", + "\r", + "const item = items[0];\r", + "\r", + "pm.test(\"Should return an entry with the key values of the item previously added and deleted.\", () => {\r", + " pm.expect(item.keyValues).to.deep.equal({\r", + " \"educationOrganizationId\": 6000203,\r", + " \"ratingTitle\": \"Test Rating Title\",\r", + " \"schoolYear\": 2022\r", + " });\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentAssessments/{{known:studentAssessment:id}}", - "host": [ - "{{ApiBaseUrl}}" ], - "path": [ - "data", - "v3", - "ed-fi", - "studentAssessments", - "{{known:studentAssessment:id}}" - ] + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/accountabilityRatings/deletes?MinChangeVersion={{known:changeVersion:minimum}}", + "host": [ + "{{ApiBaseUrl}}" + ], + "path": [ + "data", + "v3", + "ed-fi", + "accountabilityRatings", + "deletes" + ], + "query": [ + { + "key": "MinChangeVersion", + "value": "{{known:changeVersion:minimum}}" + } + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Clean up Environment Variables", - "event": [ + "name": "Teardown", + "item": [ { - "listen": "prerequest", - "script": { - "exec": [ - "// Remove all environment variables that start with \"known:\" or \"supplied:\"\r", - "_.chain(_.keys(pm.environment.toObject()))\r", - " .filter(x => _.startsWith(x, 'known:') || _.startsWith(x, 'supplied:'))\r", - " .each(k => pm.environment.unset(k)).value();" - ], - "type": "text/javascript" - } - } - ], - "request": { - "auth": { - "type": "noauth" - }, - "method": "GET", - "header": [], - "url": { - "raw": "{{ApiBaseUrl}}", - "host": [ - "{{ApiBaseUrl}}" - ] + "name": "Clean up Environment Variables", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// Remove all environment variables that start with \"known:\" or \"supplied:\"\r", + "_.chain(_.keys(pm.environment.toObject()))\r", + " .filter(x => _.startsWith(x, 'known:') || _.startsWith(x, 'supplied:'))\r", + " .each(k => pm.environment.unset(k)).value();" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}", + "host": [ + "{{ApiBaseUrl}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] } ] }, { - "name": "Custom View-based on Optional Property", + "name": "Invalid Custom View Authorization Usage", "item": [ { - "name": "Get Student Transportations", + "name": "Get Chart of Accounts (Get Many)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test(\"Status code is 200\", () => {\r", - " pm.expect(pm.response.code).to.equal(200);\r", + "pm.test(\"Status code is 500\", () => {\r", + " pm.expect(pm.response.code).to.equal(500);\r", "});\r", "\r", - "const items = pm.response.json();\r", + "const item = pm.response.json();\r", "\r", - "pm.test(\"Should return at least 1 item.\", () => {\r", - " pm.expect(items.length).to.be.greaterThan(0);\r", - "})\r", + "pm.test(\"Detail should indicate a security configuration error.\", () => {\r", + " pm.expect(item).to.deep.contain({\r", + " \"detail\": \"A security configuration problem was detected. The request cannot be authorized.\",\r", + " \"type\": \"urn:ed-fi:api:system:configuration:security\",\r", + " \"title\": \"Security Configuration Error\",\r", + " \"status\": 500,\r", + " });\r", + "});\r", "\r", - "pm.test(\"All items have transportation types containing the term 'Bus'.\", () => {\r", - " // Iterate through all items to check the assessmentIdentifier\r", - " const allContainBus = items.every(item => {\r", - " return item.transportationTypeDescriptor.indexOf(\"Bus\") >= 0;\r", - " });\r", - " \r", - " // Assert that all items pass the condition\r", - " pm.expect(allContainBus).to.be.true;\r", + "pm.test(\"Errors should contain a message indicating that there are no properties on the resource that match those required by the custom view-based authorization strategy.\", () => {\r", + " pm.expect(item.errors).to.contain(\"Unable to find a property on the authorization subject entity type 'ChartOfAccount' corresponding to the 'StudentUSI' property on the custom authorization view's basis entity type 'Student' in order to perform authorization. Should a different authorization strategy be used?\");\r", "});\r", "" ], @@ -2330,7 +3288,7 @@ "method": "GET", "header": [], "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/chartOfAccounts", "host": [ "{{ApiBaseUrl}}" ], @@ -2338,77 +3296,36 @@ "data", "v3", "ed-fi", - "studentTransportations" + "chartOfAccounts" ] } }, "response": [] }, { - "name": "Update Student Transportations (with inaccesible transportation type)", + "name": "Create Chart of Accounts", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test(\"Status code is 403\", () => {\r", - " pm.expect(pm.response.code).to.equal(403);\r", + "pm.test(\"Status code is 500\", () => {\r", + " pm.expect(pm.response.code).to.equal(500);\r", "});\r", "\r", - "pm.test(\"Detail indicates basic authorization message.\", () => {\r", - " pm.expect(pm.response.json().detail).to.match(/^Access to the requested data could not be authorized./);\r", - "});\r", - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"transportationTypeDescriptor\": \"uri://ed-fi.org/TransportationTypeDescriptor#General Public Transportation\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", - "host": [ - "{{ApiBaseUrl}}" - ], - "path": [ - "data", - "v3", - "ed-fi", - "studentTransportations" - ] - } - }, - "response": [] - }, - { - "name": "Update Student Transportations (with null transportation type)", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 403\", () => {\r", - " pm.expect(pm.response.code).to.equal(403);\r", - "});\r", + "const item = pm.response.json();\r", "\r", - "pm.test(\"Detail indicates basic authorization message.\", () => {\r", - " pm.expect(pm.response.json().detail).to.equal(\"Access to the requested data could not be authorized. The 'TransportationTypeDescriptor' value is required for authorization purposes.\");\r", + "pm.test(\"Detail should indicate a security configuration error.\", () => {\r", + " pm.expect(item).to.deep.contain({\r", + " \"detail\": \"A security configuration problem was detected. The request cannot be authorized.\",\r", + " \"type\": \"urn:ed-fi:api:system:configuration:security\",\r", + " \"title\": \"Security Configuration Error\",\r", + " \"status\": 500,\r", + " });\r", "});\r", "\r", - "pm.test(\"Type indicates an element is required.\", () => {\r", - " pm.expect(pm.response.json().type).to.equal(\"urn:ed-fi:api:security:authorization:custom-view:access-denied:element-required\");\r", + "pm.test(\"Errors should contain a message indicating that there are no properties on the resource that match those required by the custom view-based authorization strategy.\", () => {\r", + " pm.expect(item.errors).to.contain(\"Unable to find a property on the authorization subject entity type 'ChartOfAccount' corresponding to the 'StudentUSI' property on the custom authorization view's basis entity type 'Student' in order to perform authorization. Should a different authorization strategy be used?\");\r", "});\r", "" ], @@ -2422,52 +3339,7 @@ "header": [], "body": { "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", - "host": [ - "{{ApiBaseUrl}}" - ], - "path": [ - "data", - "v3", - "ed-fi", - "studentTransportations" - ] - } - }, - "response": [] - }, - { - "name": "Update Student Transportations (with accesible transportation type)", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 200\", () => {\r", - " pm.expect(pm.response.code).to.equal(200);\r", - "});\r", - "\r", - "pm.environment.set('known:studentTransportation:id', pm.response.headers.one('Location').value.split(\"/\").pop());" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": " {\r\n \"studentReference\": {\r\n \"studentUniqueId\": \"604822\"\r\n },\r\n \"transportationEducationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"specialAccomodationRequirements\": \"Wheelchair Accessibility\",\r\n \"transportationPublicExpenseEligibilityTypeDescriptor\": \"uri://ed-fi.org/TransportationPublicExpenseEligibilityTypeDescriptor#Eligible - Disability\",\r\n \"transportationTypeDescriptor\": \"uri://ed-fi.org/TransportationTypeDescriptor#Special Needs Bus\",\r\n \"studentBusDetails\": {\r\n \"busNumber\": \"Bus 101\",\r\n \"busRouteDescriptor\": \"uri://gbisd.edu/BusRouteDescriptor#101\",\r\n \"mileage\": 7.20,\r\n \"travelDayofWeeks\": [\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Wednesday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Monday\"\r\n },\r\n {\r\n \"travelDayofWeekDescriptor\": \"uri://ed-fi.org/TravelDayofWeekDescriptor#Friday\"\r\n }\r\n ],\r\n \"travelDirections\": [\r\n {\r\n \"travelDirectionDescriptor\": \"uri://ed-fi.org/TravelDirectionDescriptor#To and From School\"\r\n }\r\n ]\r\n }\r\n }", + "raw": " {\r\n \"educationOrganizationReference\": {\r\n \"educationOrganizationId\": 255901\r\n },\r\n \"fundDimensionReference\": {\r\n \"code\": \"1\",\r\n \"fiscalYear\": 2022\r\n },\r\n \"sourceDimensionReference\": {\r\n \"code\": \"1000\",\r\n \"fiscalYear\": 2022\r\n },\r\n \"accountIdentifier\": \"XYZ\",\r\n \"fiscalYear\": 2022,\r\n \"accountTypeDescriptor\": \"uri://ed-fi.org/AccountTypeDescriptor#Revenue\"\r\n }", "options": { "raw": { "language": "json" @@ -2475,7 +3347,7 @@ } }, "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations", + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/chartOfAccounts", "host": [ "{{ApiBaseUrl}}" ], @@ -2483,27 +3355,36 @@ "data", "v3", "ed-fi", - "studentTransportations" + "chartOfAccounts" ] } }, "response": [] }, { - "name": "Get Student Transportation By id", + "name": "Get Deleted Chart of Accounts", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test(\"Status code is 200\", () => {\r", - " pm.expect(pm.response.code).to.equal(200);\r", + "pm.test(\"Status code is 500\", () => {\r", + " pm.expect(pm.response.code).to.equal(500);\r", "});\r", "\r", "const item = pm.response.json();\r", "\r", - "pm.test(\"Item returned should reflect changed transportationTypeDescriptor.\", () => {\r", - " pm.expect(item.transportationTypeDescriptor).to.contain(\"Special Needs Bus\");\r", + "pm.test(\"Detail should indicate a security configuration error.\", () => {\r", + " pm.expect(item).to.deep.contain({\r", + " \"detail\": \"A security configuration problem was detected. The request cannot be authorized.\",\r", + " \"type\": \"urn:ed-fi:api:system:configuration:security\",\r", + " \"title\": \"Security Configuration Error\",\r", + " \"status\": 500,\r", + " });\r", + "});\r", + "\r", + "pm.test(\"Errors should contain a message indicating that there are no properties on the resource that match those required by the custom view-based authorization strategy.\", () => {\r", + " pm.expect(item.errors).to.contain(\"Unable to find a property on the authorization subject entity type 'ChartOfAccount' corresponding to the 'StudentUSI' property on the custom authorization view's basis entity type 'Student' in order to perform authorization. Should a different authorization strategy be used?\");\r", "});\r", "" ], @@ -2516,7 +3397,7 @@ "method": "GET", "header": [], "url": { - "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/studentTransportations/{{known:studentTransportation:id}}", + "raw": "{{ApiBaseUrl}}/data/v3/ed-fi/chartOfAccounts/deletes", "host": [ "{{ApiBaseUrl}}" ], @@ -2524,8 +3405,8 @@ "data", "v3", "ed-fi", - "studentTransportations", - "{{known:studentTransportation:id}}" + "chartOfAccounts", + "deletes" ] } }, @@ -2622,6 +3503,38 @@ } }, "response": [] + }, + { + "name": "Clean up Test Suite Environment Variables", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// Remove all environment variables that start with \"known:\" or \"supplied:\"\r", + "_.chain(_.keys(pm.environment.toObject()))\r", + " .filter(x => _.startsWith(x, 'test-suite:'))\r", + " .each(k => pm.environment.unset(k)).value();" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "{{ApiBaseUrl}}", + "host": [ + "{{ApiBaseUrl}}" + ] + } + }, + "response": [] } ] }