Skip to content

Commit

Permalink
Merge pull request #87 from DynamicsValue/feature/26-updates
Browse files Browse the repository at this point in the history
2.6.x
  • Loading branch information
jordimontana82 authored Aug 20, 2024
2 parents 42711a6 + 90c023f commit c42d4da
Show file tree
Hide file tree
Showing 58 changed files with 3,313 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

### Added

- Added new InMemoryFileDb implementation to support file and image storage - https://github.com/DynamicsValue/fake-xrm-easy/issues/157
- Added default max file size for file and image uploads - https://github.com/DynamicsValue/fake-xrm-easy/issues/157

### Changed

- Resolves an issue in FetchXml queries when using arithmetic values and no early bound assemblies are used. It will now read from injected metadata in absence of proxy type assemblies - https://github.com/DynamicsValue/fake-xrm-easy/issues/158
- Resolves issue in MetadataGenerator where relationship properties were generated in the wrong order, also generates ManyToMany relationship properties - https://github.com/DynamicsValue/fake-xrm-easy/issues/135
- Adds implementation of RelatedEntities in Update message , before it was implemented only for Create - https://github.com/DynamicsValue/fake-xrm-easy/issues/154

Expand Down
22 changes: 20 additions & 2 deletions src/FakeXrmEasy.Core/Db/InMemoryDb.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FakeXrmEasy.Core.Db.Exceptions;
using System;
using FakeXrmEasy.Core.Db.Exceptions;
using FakeXrmEasy.Extensions;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
Expand Down Expand Up @@ -105,13 +106,30 @@ protected internal void AddOrUpdateMetadata(string logicalName, EntityMetadata e

protected internal void AddEntityRecord(Entity e)
{
InMemoryTable table;
if (!ContainsTable(e.LogicalName))
{
InMemoryTable table;
AddTable(e.LogicalName, out table);
}
else
{
table = GetTable(e.LogicalName);
}

table.Add(e);
}

protected internal bool ContainsEntityRecord(string logicalName, Guid id)
{
if (!ContainsTable(logicalName))
{
return false;
}

var table = GetTable(logicalName);
return table.Contains(id);
}

protected internal void AddOrReplaceEntityRecord(Entity e)
{
InMemoryTable table = null;
Expand Down
9 changes: 9 additions & 0 deletions src/FakeXrmEasy.Core/Db/InMemoryTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,14 @@ protected internal void SetMetadata(EntityMetadata entityMetadata)
{
_metadata._entityMetadata = entityMetadata.Copy();
}

/// <summary>
/// Returns the entity metadata associated to this column
/// </summary>
/// <returns></returns>
protected internal EntityMetadata GetEntityMetadata()
{
return _metadata._entityMetadata;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace FakeXrmEasy.Core.Exceptions.Query.FetchXml
{
/// <summary>
/// Exception raised in a query when an attribute value type could not be determined correctly
/// </summary>
public class ArithmeticTypeConversionException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="entityName"></param>
/// <param name="attributeName"></param>
internal ArithmeticTypeConversionException(string entityName, string attributeName) :
base($"When using arithmetic values in a condition of attribute '{attributeName}' of entity '{entityName}' in a Fetch a ProxyTypesAssembly must be used in order to know which types to cast values to. If you are using early bound types, please make sure the early bound type was generated for entity '{entityName}'")
{

}
}
}
48 changes: 31 additions & 17 deletions src/FakeXrmEasy.Core/Extensions/XmlExtensionsForFetchXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Globalization;
using FakeXrmEasy.Abstractions;
using FakeXrmEasy.Abstractions.Exceptions;
using FakeXrmEasy.Core.Exceptions.Query.FetchXml;

namespace FakeXrmEasy.Extensions.FetchXml
{
Expand Down Expand Up @@ -898,6 +899,26 @@ public static bool ValueNeedsConverting(ConditionOperator conditionOperator)
return !OperatorsNotToConvertArray.Contains(conditionOperator);
}

internal static object GetConditionExpressionBasedOnAttributeType(Type attributeType, string value, string sEntityName, string sAttributeName, ConditionOperator op)
{
try
{
if (ValueNeedsConverting(op))
{
return GetValueBasedOnType(attributeType, value);
}

else
{
return int.Parse(value);
}
}
catch (Exception e)
{
throw new Exception(string.Format("When trying to parse value for entity {0} and attribute {1}: {2}", sEntityName, sAttributeName, e.Message));
}
}

/// <summary>
///
/// </summary>
Expand All @@ -919,25 +940,18 @@ public static object GetConditionExpressionValueCast(string value, IXrmFakedCont
var attributeType = ctx.FindReflectedAttributeType(reflectedType, sEntityName, sAttributeName);
if (attributeType != null)
{
try
{
if (ValueNeedsConverting(op))
{
return GetValueBasedOnType(attributeType, value);
}

else
{
return int.Parse(value);
}
}
catch (Exception e)
{
throw new Exception(string.Format("When trying to parse value for entity {0} and attribute {1}: {2}", sEntityName, sAttributeName, e.Message));
}
return GetConditionExpressionBasedOnAttributeType(attributeType, value, sEntityName, sAttributeName, op);
}
}
}
else
{
var injectedAttributeType = ctx.FindAttributeTypeInInjectedMetadata(sEntityName, sAttributeName);
if (injectedAttributeType != null)
{
return GetConditionExpressionBasedOnAttributeType(injectedAttributeType, value, sEntityName, sAttributeName, op);
}
}

#if FAKE_XRM_EASY_9
if(op == ConditionOperator.ContainValues || op == ConditionOperator.DoesNotContainValues)
Expand Down Expand Up @@ -976,7 +990,7 @@ public static object GetConditionExpressionValueCast(string value, IXrmFakedCont

if (bIsNumeric || bIsDateTime)
{
throw new Exception($"When using arithmetic values in a condition of attribute '{sAttributeName}' of entity '{sEntityName}' in a Fetch a ProxyTypesAssembly must be used in order to know which types to cast values to. If you are using early bound types, please make sure the early bound type was generated for entity '{sEntityName}'");
throw new ArithmeticTypeConversionException(sEntityName, sAttributeName);
}

//Default value
Expand Down
12 changes: 6 additions & 6 deletions src/FakeXrmEasy.Core/FakeXrmEasy.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,22 @@
</ItemGroup>

<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY'">
<PackageReference Include="FakeXrmEasy.Abstractions.v2011" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v2011" Version="[2.6.0-*,3.0)" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2013'">
<PackageReference Include="FakeXrmEasy.Abstractions.v2013" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v2013" Version="[2.6.0-*,3.0)" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2015'">
<PackageReference Include="FakeXrmEasy.Abstractions.v2015" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v2015" Version="[2.6.0-*,3.0)" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2016'">
<PackageReference Include="FakeXrmEasy.Abstractions.v2016" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v2016" Version="[2.6.0-*,3.0)" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_365'">
<PackageReference Include="FakeXrmEasy.Abstractions.v365" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v365" Version="[2.6.0-*,3.0)" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_9'">
<PackageReference Include="FakeXrmEasy.Abstractions.v9" Version="[2.5.0-*,3.0)" />
<PackageReference Include="FakeXrmEasy.Abstractions.v9" Version="[2.6.0-*,3.0)" />
</ItemGroup>

<Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception raised when InitializeFiles is called more than once.
/// </summary>
public class AlreadyInitializedFilesException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
public AlreadyInitializedFilesException() : base("InitializeFiles has been called more than once. Always initialize all the files you need in a single call to .InitializeFiles()")
{

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception raised when a file is uploaded and its file extension is blocked by the BlockedAttachment settings
/// </summary>
public class BlockedAttachmentException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
internal BlockedAttachmentException(string fileName) : base($"The attachment with file name '{fileName}' is not a valid file extension type")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception raised when a file is uploaded and its file MIME type is blocked by either the BlockedMimeType or AllowedMimeType settings
/// </summary>
public class BlockedMimeTypeException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
internal BlockedMimeTypeException(string fileName, string mimeType) : base($"The MIME Type '{mimeType}' for file name '{fileName}' is not a valid")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Internal exception used for internal testing only thrown when a file could not be added to the InMemoryFileDb
/// </summary>
public class CouldNotAddFileException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
internal CouldNotAddFileException(): base("A file could not be added")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Throws an exception when a file could not be committed due to an unknown error
/// </summary>
public class CouldNotCommitFileException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="fileUploadContinuationToken"></param>
internal CouldNotCommitFileException(string fileUploadContinuationToken) : base($"The file associated to continuation token '{fileUploadContinuationToken}' could not be committed due to an unknown error")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception thrown when a particular file could not be deleted or it doesn't exists
/// </summary>
public class CouldNotDeleteFileException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="fileId"></param>
internal CouldNotDeleteFileException(string fileId) : base($"Could not delete file with Id '{fileId}'")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception raised when a block id already exists in the current file upload session
/// </summary>
public class DuplicateFileBlockException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="blockId">The block Id that already existed</param>
/// <param name="fileUploadSessionId">The Id of the FileUploadSession where that block existed</param>
internal DuplicateFileBlockException(string blockId, string fileUploadSessionId) : base($"A block was already uploaded with Id {blockId} against the current file continuation token: {fileUploadSessionId}")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using Microsoft.Xrm.Sdk;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception raised when downloading a file block for a database record and column that doesn't actually have a file against it
/// </summary>
public class FileToDownloadNotFoundException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="entityReference">An entity reference of the record</param>
/// <param name="fileAttributeName">The column where a file was not found</param>
internal FileToDownloadNotFoundException(EntityReference entityReference, string fileAttributeName)
: base($"A file was not found for record with logical name '{entityReference.LogicalName}' and Id '{entityReference.Id.ToString()}' in column '{fileAttributeName}'")
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
{
/// <summary>
/// Exception thrown when a file continuation token could not be found or invalid, either when initiating a file upload or a file download
/// </summary>
public class FileTokenContinuationNotFoundException: Exception
{
/// <summary>
/// Default constructor
/// </summary>
/// <param name="fileContinuationTokenId">The file continuation token that could not be found</param>
internal FileTokenContinuationNotFoundException(string fileContinuationTokenId)
: base($"The file continuation token with Id '{fileContinuationTokenId}' could not be found or has already been committed")
{

}
}
}
Loading

0 comments on commit c42d4da

Please sign in to comment.