├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yml ├── pull_request_template.md ├── release-notes.sh └── workflows │ ├── build_and_test.yml │ └── release.yml ├── .gitignore ├── .netconfig ├── CHANGELOG.md ├── Directory.Build.props ├── LICENSE ├── README.md ├── SignNow.Net.Examples ├── Document group │ └── DocumentGroupOperations.cs ├── Documents │ ├── CheckTheStatusOfTheDocument.cs │ ├── CreateOneTimeLinkToDownloadTheDocument.cs │ ├── CreateSigningLinkToTheDocument.cs │ ├── DownloadSignedDocument.cs │ ├── GetTheDocumentHistory.cs │ ├── MergeTwoDocuments.cs │ ├── MoveTheDocumentToFolder.cs │ ├── PrefillTextFields.cs │ ├── UploadDocument.cs │ ├── UploadDocumentWithComplexTags.cs │ └── UploadDocumentWithTags.cs ├── ExamplesBase.cs ├── Folders │ ├── CreateFolder.cs │ ├── DeleteFolder.cs │ ├── GetAllFolders.cs │ ├── GetFolder.cs │ └── RenameFolder.cs ├── Invites │ ├── CreateEmbeddedSigningInviteToSignTheDocument.cs │ ├── CreateFreeformInviteToSignTheDocument.cs │ └── CreateRoleBasedInviteToSignTheDocument.cs ├── OAuth2 │ ├── GenerateAccessToken.cs │ ├── RefreshAccessToken.cs │ └── VerifyAccessToken.cs ├── SignNow.Net.Examples.csproj ├── Template │ ├── CreateDocumentFromTheTemplate.cs │ └── CreateTemplateFromTheDocument.cs ├── TestExamples │ ├── ComplexTags.pdf │ ├── DocumentWithSignatureFieldTag.pdf │ └── SignAndDate.pdf ├── Users │ ├── ChangeUserDetails.cs │ ├── CreateSignNowUser.cs │ ├── GetUserDocuments.cs │ └── GetUserModifiedDocuments.cs └── Webhooks │ └── CreateEventSubscriptionForDocument.cs ├── SignNow.Net.Test ├── AcceptanceTests │ ├── DocumentServiceTest.CreateSigningLink.cs │ ├── DocumentServiceTest.Delete.cs │ ├── DocumentServiceTest.Download.cs │ ├── DocumentServiceTest.Templates.cs │ ├── DocumentServiceTest.Upload.cs │ ├── DocumentServiceTest.cs │ ├── FolderServiceTest.cs │ ├── OAuth2ServiceTest.cs │ ├── SignNowExceptionTest.cs │ └── UserServiceTest.cs ├── AssertExtensions.cs ├── AuthorizedApiTestBase.cs ├── Constants │ └── ErrorMessages.cs ├── Context │ ├── CredentialLoader.cs │ ├── CredentialModel.cs │ ├── ICredentialProvider.cs │ ├── JsonCredentialProvider.cs │ └── JsonFileCredentialProvider.cs ├── Directory.Build.props ├── FeatureTests │ ├── DotnetTest.cs │ ├── EmbeddedSigningTest.cs │ ├── FreeFormInviteTest.cs │ └── RoleBasedInviteTest.cs ├── GlobalSuppressions.cs ├── SignNow.Net.Test.csproj ├── SignNow.Net.Test.csproj.DotSettings ├── SignNowTestBase.cs ├── TestData │ ├── Documents │ │ ├── DocumentUpload.pdf │ │ └── DocumentUpload.txt │ └── FakeModels │ │ ├── DocumentHistoryResponseFaker.cs │ │ ├── EditFields │ │ └── TextFieldFaker.cs │ │ ├── EmbeddedInviteFaker.cs │ │ ├── FieldContentsFaker.cs │ │ ├── FieldFaker.cs │ │ ├── FieldInviteFaker.cs │ │ ├── FreeFormInviteFaker.cs │ │ ├── RoleFaker.cs │ │ ├── SignNowDocumentFaker.cs │ │ ├── SignNowFoldersFaker.cs │ │ ├── ThumbnailFaker.cs │ │ ├── TokenFaker.cs │ │ └── UserFaker.cs ├── TestUtils.cs └── UnitTests │ ├── Context │ └── CredentialLoaderTest.cs │ ├── Exceptions │ ├── SignNowExceptionTest.AggregateExceptions.cs │ └── SignNowExceptionTest.cs │ ├── Extensions │ ├── ScopeExtensionsTest.cs │ └── ValidatorExtensionsTest.cs │ ├── Helpers │ ├── Converters │ │ ├── Base64ToStringJsonConverter.cs │ │ ├── BoolToIntJsonConverterTest.cs │ │ ├── StringToBoolJsonConverterTest.cs │ │ ├── StringToIntJsonConverterTest.cs │ │ ├── StringToUriJsonConverterTest.cs │ │ └── UnixTimeStampJsonConverterTest.cs │ ├── GuardTest.cs │ └── UserAgentSdkHeadersTest.cs │ ├── Infrastructure │ ├── RuntimeInfoTest.cs │ └── SdkRuntimeTest.cs │ ├── Models │ ├── ComplexTags │ │ ├── ComplexTagsTest.cs │ │ └── RadioButtonTagTest.cs │ ├── EditFields │ │ └── TextFieldTest.cs │ ├── EmbeddedInviteTest.cs │ ├── FieldContentsTest.cs │ ├── FieldInvitesTest.cs │ ├── FreeformInviteTest.cs │ ├── Internal │ │ ├── ErrorResponseTest.cs │ │ ├── FieldTest.cs │ │ └── RoleContentTest.cs │ ├── RequestOptionsTest.cs │ ├── RoleTest.cs │ ├── SignInviteTest.RoleBased.cs │ ├── SignInviteTest.cs │ ├── SignNowDocumentTest.cs │ ├── SignNowFoldersTest.cs │ ├── SignatureTest.cs │ ├── ThumbnailTest.cs │ ├── TokenTest.cs │ └── UserTest.cs │ ├── Requests │ ├── CopyDocumentGroupRequestTest.cs │ ├── CreateEmbeddedSigningInviteRequestTest.cs │ ├── CreateEventSubscriptionTest.cs │ ├── DownloadOptionsTest.cs │ ├── EditFieldRequestTest.cs │ ├── EmbeddedSigningLinkRequestTest.cs │ ├── GetAccessTokenRequestTest.cs │ ├── GetFolderOptionsTest.cs │ ├── LimitOffsetOptionsTest.cs │ ├── MergeDocumentRequestTest.cs │ ├── MultipartHttpContentTest.cs │ ├── PagePaginationOptionsTest.cs │ ├── PrefillTextFieldRequestTest.cs │ ├── UpdateEventSubscriptionTest.cs │ └── UpdateUserOptionsTest.cs │ ├── Responses │ ├── DocumentGroupInfoResponseTest.cs │ ├── DocumentGroupsResponseTests.cs │ ├── DocumentHistoryResponseTest.cs │ ├── EmbeddedInviteResponseTest.cs │ └── EventSubscriptionResponseTest.cs │ └── Services │ ├── DocumentGroupServiceTest.cs │ ├── DocumentServiceTest.cs │ ├── FolderServiceTest.cs │ ├── OAuth2ServiceTest.cs │ ├── SignNowClientTest.cs │ ├── SignNowContextTest.cs │ └── UserServiceTest.cs ├── SignNow.Net.sln ├── SignNow.Net ├── Exceptions │ ├── ExceptionMessages.Designer.cs │ ├── ExceptionMessages.resx │ └── SignNowException.cs ├── Interfaces │ ├── IContent.cs │ ├── IDocumentGroup.cs │ ├── IDocumentService.cs │ ├── IEventSubscriptionService.cs │ ├── IFieldEditable.cs │ ├── IFolderService.cs │ ├── IHttpContentAdapter.cs │ ├── IOAuth2Service.cs │ ├── IQueryToString.cs │ ├── ISignInvite.cs │ ├── ISignNowClient.cs │ ├── ISignNowContent.cs │ ├── ISignNowContext.cs │ ├── ISignNowField.cs │ ├── ISignNowInviteStatus.cs │ ├── ITextTags.cs │ └── IUserService.cs ├── Model │ ├── Company.cs │ ├── ComplexTags │ │ ├── AttachmentTag.cs │ │ ├── CheckBoxTag.cs │ │ ├── ComplexTagBase.cs │ │ ├── DateValidatorTag.cs │ │ ├── DropdownTag.cs │ │ ├── HyperlinkTag.cs │ │ ├── InitialsTag.cs │ │ ├── RadioButtonTag.cs │ │ ├── SignatureTag.cs │ │ └── TextTag.cs │ ├── ComplexTextTags.cs │ ├── DataValidator.cs │ ├── DownloadType.cs │ ├── EditFields │ │ ├── AbstractField.cs │ │ └── TextField.cs │ ├── EmbeddedInvite.cs │ ├── EventSubscription.cs │ ├── EventType.cs │ ├── Field.cs │ ├── FieldContents │ │ ├── AttachmentContent.cs │ │ ├── BaseContent.cs │ │ ├── CheckboxContent.cs │ │ ├── EnumerationContent.cs │ │ ├── FieldJsonAttributes.cs │ │ ├── HyperlinkContent.cs │ │ ├── RadiobuttonContent.cs │ │ ├── SignatureContent.cs │ │ └── TextContent.cs │ ├── GrantType.cs │ ├── Lang.cs │ ├── Organization.cs │ ├── Owner.cs │ ├── Pagination.cs │ ├── RedirectTarget.cs │ ├── RequestOptions.cs │ ├── Requests │ │ ├── CreateEmbedLinkOptions.cs │ │ ├── CreateEventSubscription.cs │ │ ├── CreateUserOptions.cs │ │ ├── DocumentGroup │ │ │ ├── CopyDocumentGroupRequest.cs │ │ │ ├── DocumentHistoryType.cs │ │ │ ├── DownloadOptions.cs │ │ │ └── DownloadType.cs │ │ ├── EventSubscriptionBase │ │ │ ├── AbstractEventSubscription.cs │ │ │ └── EventCreateAttributes.cs │ │ ├── GetFolderOptions.cs │ │ ├── GetFolderQuery │ │ │ ├── FolderFilters.cs │ │ │ ├── FolderOptions.cs │ │ │ └── FolderSort.cs │ │ ├── JsonHttpContent.cs │ │ ├── LimitOffsetOptions.cs │ │ ├── MultipartHttpContent.cs │ │ ├── PagePaginationOptions.cs │ │ ├── UpdateEventSubscription.cs │ │ └── UpdateUserOptions.cs │ ├── Responses │ │ ├── CreateDocumentFromTemplateResponse.cs │ │ ├── CreateTemplateFromDocumentResponse.cs │ │ ├── DocumentGroupCreateResponse.cs │ │ ├── DocumentGroupInfoResponse.cs │ │ ├── DocumentGroupsResponse.cs │ │ ├── DocumentHistoryResponse.cs │ │ ├── DownloadDocumentResponse.cs │ │ ├── DownloadLinkResponse.cs │ │ ├── EditDocumentResponse.cs │ │ ├── EmbeddedInviteLinkResponse.cs │ │ ├── EmbeddedInviteResponse.cs │ │ ├── EventHistoryListResponse.cs │ │ ├── EventSubscriptionInfoResponse.cs │ │ ├── EventSubscriptionResponse.cs │ │ ├── EventUpdateResponse.cs │ │ ├── FolderIdentityResponse.cs │ │ ├── GenericResponses │ │ │ └── IdResponse.cs │ │ ├── InviteResponse.cs │ │ ├── MetaInfo.cs │ │ ├── SigningLinkResponse.cs │ │ ├── SuccessStatusResponse.cs │ │ ├── UploadDocumentResponse.cs │ │ ├── UserCreateResponse.cs │ │ └── UserUpdateResponse.cs │ ├── Role.cs │ ├── Scope.cs │ ├── SignInvite.cs │ ├── SignNowDocument.Fields.cs │ ├── SignNowDocument.cs │ ├── SignNowFolders.cs │ ├── SignNowInvite.cs │ ├── SignStatus.cs │ ├── SignerOptions.cs │ ├── Thumbnail.cs │ ├── Token.cs │ ├── TokenType.cs │ ├── User.cs │ └── UserBilling.cs ├── Properties │ └── AsseblyInfo.cs ├── Service │ ├── DocumentGroupService.cs │ ├── DocumentService.cs │ ├── EventSubscriptionService.cs │ ├── FolderService.cs │ ├── OAuth2Service.cs │ ├── SignNowClient.cs │ ├── UserService.cs │ └── WebClientBase.cs ├── SignNow.Net.csproj ├── SignNowContext.cs ├── _Internal │ ├── Constants │ │ └── ApiUrl.cs │ ├── Extensions │ │ ├── ScopeExtensions.cs │ │ └── ValidatorExtensions.cs │ ├── Helpers │ │ ├── Converters │ │ │ ├── BoolToIntJsonConverter.cs │ │ │ ├── BoolToStringJsonConverter.cs │ │ │ ├── BoolToStringYNJsonConverter.cs │ │ │ ├── KeyValueOrEmptyArrayConverter.cs │ │ │ ├── StringBase64ToByteArrayJsonConverter.cs │ │ │ ├── StringToBoolJsonConverter.cs │ │ │ ├── StringToIntJsonConverter.cs │ │ │ ├── StringToUriJsonConverter.cs │ │ │ └── UnixTimeStampJsonConverter.cs │ │ ├── Guard.cs │ │ ├── HttpContentAdapter.cs │ │ └── UserAgentSdkHeaders.cs │ ├── Infrastructure │ │ ├── RuntimeInfo.cs │ │ └── SdkRuntime.cs │ ├── Model │ │ ├── ErrorResponse.cs │ │ └── SignerAuthorization.cs │ └── Requests │ │ ├── CreateDocumentFromTemplateRequest.cs │ │ ├── CreateDocumentGroupRequest.cs │ │ ├── CreateInviteRequest.cs │ │ ├── CreateOrRenameFolderRequest.cs │ │ ├── CreateSigningLinkRequest.cs │ │ ├── CreateTemplateFromDocumentRequest.cs │ │ ├── EditFieldRequest.cs │ │ ├── EmbeddedSigningLinkRequest.cs │ │ ├── EmbeddedSigningRequest.cs │ │ ├── GetAccessTokenRequest.cs │ │ ├── MergeDocumentRequest.cs │ │ ├── MoveDocumentGroupRequest.cs │ │ ├── MoveDocumentRequest.cs │ │ ├── PrefillTextFieldRequest.cs │ │ ├── RenameDocumentGroupRequest.cs │ │ └── SendVerificationEmailRequest.cs └── icon.png ├── SignNow.props ├── codecov.yml ├── netfx.props └── release-notes.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set the default behavior, in case people don't have core.autocrlf set. 3 | # https://help.github.com/en/articles/configuring-git-to-handle-line-endings 4 | ############################################################################### 5 | * text=auto 6 | 7 | ############################################################################### 8 | # Set default behavior for command prompt diff. 9 | # 10 | # This is need for earlier builds of msysgit that does not have it on by 11 | # default for csharp files. 12 | # Note: This is only used by command line 13 | ############################################################################### 14 | *.cs diff=csharp 15 | 16 | ############################################################################### 17 | # Set the merge driver for project and solution files 18 | # 19 | # Merging from the command prompt will add diff markers to the files if there 20 | # are conflicts (Merging from VS is not affected by the settings below, in VS 21 | # the diff markers are never inserted). Diff markers may cause the following 22 | # file extensions to fail to load in VS. An alternative would be to treat 23 | # these files as binary and thus will always conflict and require user 24 | # intervention with every merge. To do so, just uncomment the entries below 25 | ############################################################################### 26 | #*.sln merge=binary 27 | #*.csproj merge=binary 28 | #*.vbproj merge=binary 29 | #*.vcxproj merge=binary 30 | #*.vcproj merge=binary 31 | #*.dbproj merge=binary 32 | #*.fsproj merge=binary 33 | #*.lsproj merge=binary 34 | #*.wixproj merge=binary 35 | #*.modelproj merge=binary 36 | #*.sqlproj merge=binary 37 | #*.wwaproj merge=binary 38 | 39 | ############################################################################### 40 | # behavior for image files 41 | # 42 | # image files are treated as binary by default. 43 | ############################################################################### 44 | #*.jpg binary 45 | #*.png binary 46 | #*.gif binary 47 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | # Set update schedule for GitHub Actions 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## By creating this pull request, I confirm the following: 2 | * [ ] I have read the **[CONTRIBUTING](https://github.com/signnow/SignNow.NET/blob/develop/README.md#contribution-guidelines)** document. 3 | * [ ] My change requires a change to the documentation. 4 | * [ ] I have added tests to cover my changes. 5 | * [ ] I have updated the documentation accordingly. 6 | * [ ] I updated the CHANGELOG. 7 | 8 | ## Types of changes: 9 | 10 | * [ ] Bug fix (non-breaking change which fixes an issue) 11 | * [ ] New feature (non-breaking change which adds functionality) 12 | * [ ] Breaking change (fix or feature that would cause existing functionality to change) 13 | * [ ] Link to issue (if exists): 14 | 15 | ## Small description of changes: 16 | 17 | 18 | Thanks 19 | -------------------------------------------------------------------------------- /.github/release-notes.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # -e Exit immediately if a command exits with a non-zero status. 4 | # -u Treat unset variables as an error when substituting. 5 | 6 | set -eu 7 | set -o pipefail 8 | 9 | # Gets Release notes for the latest release from CHANGELOG.md 10 | # 11 | # This script takes description in `markdown` format from CHANGELOG.md file 12 | # You must to use the `markdown` H2 tag for the release version 13 | # and `markdown` H3 tag for the description 14 | # 15 | # Script will return the content between the first and second string occurrences 16 | # that start with H2 markdown tag with release version: example: `## [1.0.0]` 17 | # 18 | # How to use: 19 | # release-notes.sh CHANGELOG.md 20 | 21 | 22 | # Searching for line which starts from markdown H2 tag: ## [1.0.0] 23 | VERSION_PATTERN="^## \[[0-9]+\\.[0-9]+\\.[0-9]+]" 24 | 25 | startLine=$(($(cat < "$1" | grep -nE "$VERSION_PATTERN" | head -n 1 | tail -n 1 | cut -d ":" -f 1) + 1)) 26 | finishLine=$(($(cat < "$1" | grep -nE "$VERSION_PATTERN" | head -n 2 | tail -n 1 | cut -d ":" -f 1) - 1)) 27 | changelog=$(sed -n "${startLine},${finishLine}p" "$1"); 28 | 29 | echo "${changelog}" 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SignNow.NET gitignore 2 | # 3 | # OS and IDE specific ignoring files shold be configured 4 | # into ~/.global_gitignore 5 | # @see: https://help.github.com/en/articles/ignoring-files#create-a-global-gitignore 6 | # 7 | 8 | # ignore local files with API credentials 9 | *.signnow.com.json 10 | -------------------------------------------------------------------------------- /.netconfig: -------------------------------------------------------------------------------- 1 | [ReportGenerator] 2 | reports = SignNow.Net.Test/bin/Debug/net462/coverage.net462.opencover.xml 3 | reports = SignNow.Net.Test/bin/Debug/net7.0/coverage.net7.0.opencover.xml 4 | reports = SignNow.Net.Test/bin/Debug/net8.0/coverage.net8.0.opencover.xml 5 | targetdir = "SignNow.Net.Test/bin/coverage-html" 6 | reporttypes = Html;HtmlSummary 7 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildThisFileDirectory) 5 | Debug 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 airSlate Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/CheckTheStatusOfTheDocument.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class DocumentExamples 9 | { 10 | [TestMethod] 11 | public async Task CheckTheStatusOfTheDocumentAsync() 12 | { 13 | // upload a document with a signature field 14 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 15 | var document = await testContext.Documents 16 | .UploadDocumentWithFieldExtractAsync(fileStream, "CheckTheStatusOfTheDocument.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // get the document 20 | var documentStatus = await testContext.Documents 21 | .GetDocumentAsync(document?.Id) 22 | .ConfigureAwait(false); 23 | 24 | // check the status of the document 25 | Assert.AreEqual(DocumentStatus.NoInvite, documentStatus.Status); 26 | 27 | // delete the test document 28 | DeleteTestDocument(document?.Id); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/CreateOneTimeLinkToDownloadTheDocument.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace SignNow.Net.Examples 6 | { 7 | public partial class DocumentExamples 8 | { 9 | [TestMethod] 10 | public async Task CreateOneTimeLinkToDownloadTheDocumentAsync() 11 | { 12 | // Upload a document with a signature field 13 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 14 | var document = await testContext.Documents 15 | .UploadDocumentWithFieldExtractAsync(fileStream, "CreateOneTimeLinkToDownloadTheDocumentTest.pdf") 16 | .ConfigureAwait(false); 17 | 18 | // Create a one-time use URL for anyone to download the document as a PDF 19 | var oneTimeLink = await testContext.Documents 20 | .CreateOneTimeDownloadLinkAsync(document?.Id) 21 | .ConfigureAwait(false); 22 | 23 | // Check if the URL is valid 24 | StringAssert.Contains(oneTimeLink.Url.Host, "signnow.com"); 25 | 26 | // Clean up 27 | DeleteTestDocument(document?.Id); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/CreateSigningLinkToTheDocument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class DocumentExamples 9 | { 10 | [TestMethod] 11 | public async Task CreateSigningLinkToTheDocumentAsync() 12 | { 13 | // Upload a document with a signature field 14 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 15 | var document = await testContext.Documents 16 | .UploadDocumentWithFieldExtractAsync(fileStream, "CreateSigningLinkToTheDocument.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // Create a signing link to the document for signature 20 | var signingLink = await testContext.Documents 21 | .CreateSigningLinkAsync(document?.Id) 22 | .ConfigureAwait(false); 23 | 24 | // Validate the response 25 | Assert.IsNotNull(signingLink.Url); 26 | Assert.IsNotNull(signingLink.AnonymousUrl); 27 | Assert.IsInstanceOfType(signingLink.Url, typeof(Uri)); 28 | Assert.AreEqual("https", signingLink.Url.Scheme); 29 | Assert.IsFalse(string.IsNullOrEmpty(signingLink.Url.OriginalString)); 30 | 31 | // Clean up 32 | DeleteTestDocument(document?.Id); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/DownloadSignedDocument.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class DocumentExamples 9 | { 10 | [TestMethod] 11 | public async Task DownloadSignedDocumentAsync() 12 | { 13 | // Upload document 14 | await using var fileStream = File.OpenRead(PdfWithoutFields); 15 | var document = await testContext.Documents 16 | .UploadDocumentAsync(fileStream, "SignedDocumentTest.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // Download signed document 20 | var documentSigned = await testContext.Documents 21 | .DownloadDocumentAsync(document.Id, DownloadType.PdfCollapsed) 22 | .ConfigureAwait(false); 23 | 24 | // Check if document is downloaded 25 | Assert.AreEqual("SignedDocumentTest.pdf", documentSigned.Filename); 26 | Assert.IsInstanceOfType(documentSigned.Document, typeof(Stream)); 27 | 28 | // Clean up 29 | DeleteTestDocument(document.Id); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/GetTheDocumentHistory.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class DocumentExamples 9 | { 10 | [TestMethod] 11 | public async Task GetTheDocumentHistoryAsync() 12 | { 13 | // upload a document with a signature field 14 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 15 | var document = await testContext.Documents 16 | .UploadDocumentWithFieldExtractAsync(fileStream, "GetTheDocumentHistory.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // get the document history 20 | var documentHistory = await testContext.Documents 21 | .GetDocumentHistoryAsync(document?.Id) 22 | .ConfigureAwait(false); 23 | 24 | // check the document history 25 | Assert.IsTrue(documentHistory.All(item => item.DocumentId == document?.Id)); 26 | Assert.IsTrue(documentHistory.Any(item => item.Origin == "original")); 27 | Assert.IsTrue(documentHistory.All(item => item.Email == credentials.Login)); 28 | 29 | // Clean up 30 | DeleteTestDocument(document?.Id); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/MergeTwoDocuments.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using SignNow.Net.Model; 6 | 7 | namespace SignNow.Net.Examples 8 | { 9 | public partial class DocumentExamples 10 | { 11 | [TestMethod] 12 | public async Task MergeTwoDocumentsAsync() 13 | { 14 | // upload two documents 15 | await using var file1Stream = File.OpenRead(PdfWithSignatureField); 16 | await using var file2Stream = File.OpenRead(PdfWithoutFields); 17 | 18 | var doc1 = await testContext.Documents 19 | .UploadDocumentWithFieldExtractAsync(file1Stream, "MergeTwoDocumentsTest1.pdf") 20 | .ConfigureAwait(false); 21 | var doc2 = await testContext.Documents 22 | .UploadDocumentWithFieldExtractAsync(file2Stream, "MergeTwoDocumentsTest2.pdf") 23 | .ConfigureAwait(false); 24 | 25 | // get uploaded documents 26 | var document1 = await testContext.Documents.GetDocumentAsync(doc1.Id).ConfigureAwait(false); 27 | var document2 = await testContext.Documents.GetDocumentAsync(doc2.Id).ConfigureAwait(false); 28 | 29 | // merge two documents 30 | var documents = new List { document1, document2 }; 31 | var finalDocument = await testContext.Documents 32 | .MergeDocumentsAsync("MergeTwoDocumentsTestResult.pdf", documents) 33 | .ConfigureAwait(false); 34 | 35 | // check merged document 36 | Assert.AreEqual("MergeTwoDocumentsTestResult.pdf", finalDocument.Filename); 37 | Assert.IsInstanceOfType(finalDocument.Document, typeof(Stream) ); 38 | 39 | // clean up 40 | await testContext.Documents.DeleteDocumentAsync(doc1.Id); 41 | await testContext.Documents.DeleteDocumentAsync(doc2.Id); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/UploadDocument.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace SignNow.Net.Examples 6 | { 7 | public partial class DocumentExamples 8 | { 9 | [TestMethod] 10 | public async Task UploadDocumentAsync() 11 | { 12 | await using var fileStream = File.OpenRead(PdfWithoutFields); 13 | 14 | // Upload the document 15 | var uploadResponse = await testContext.Documents 16 | .UploadDocumentAsync(fileStream, "document-example.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // Gets document after from successful upload 20 | var uploadedDocument = await testContext.Documents 21 | .GetDocumentAsync(uploadResponse.Id) 22 | .ConfigureAwait(false); 23 | 24 | // Check uploaded document 25 | Assert.AreEqual(uploadResponse.Id, uploadedDocument.Id); 26 | 27 | // clean up 28 | DeleteTestDocument(uploadedDocument.Id); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Documents/UploadDocumentWithTags.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | [TestClass] 9 | public partial class DocumentExamples : ExamplesBase 10 | { 11 | [TestMethod] 12 | public async Task UploadDocumentWithTagsAsync() 13 | { 14 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 15 | 16 | // Upload the document with field extract 17 | var documentWithFields = await testContext.Documents 18 | .UploadDocumentWithFieldExtractAsync(fileStream, "DocumentSampleWithSignatureTextTag.pdf") 19 | .ConfigureAwait(false); 20 | 21 | // Get uploaded document 22 | var uploadedDocument = await testContext.Documents 23 | .GetDocumentAsync(documentWithFields.Id) 24 | .ConfigureAwait(false); 25 | 26 | // Check that document has fields 27 | using var documentFields = uploadedDocument?.Fields.GetEnumerator(); 28 | documentFields?.MoveNext(); 29 | 30 | Assert.AreEqual(FieldType.Text, documentFields?.Current?.Type); 31 | Assert.IsTrue(uploadedDocument?.Fields.Count > 0); 32 | 33 | // clean up 34 | DeleteTestDocument(uploadedDocument.Id); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Folders/CreateFolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using SignNow.Net.Model.Requests; 6 | 7 | namespace SignNow.Net.Examples 8 | { 9 | public partial class FolderExamples: ExamplesBase 10 | { 11 | [TestMethod] 12 | public async Task CreateFolderAsync() 13 | { 14 | // Get Root folder and Documents folder 15 | var root = await testContext.Folders.GetAllFoldersAsync().ConfigureAwait(false); 16 | var documentsFolder = root.Folders.FirstOrDefault(f => f.Name == "Documents"); 17 | 18 | var timestamp = (long)(DateTime.Now - UnixEpoch).TotalSeconds; 19 | // Note: You should use different folder name for each example run 20 | var myFolderName = $"CreateFolderExample_{timestamp}"; 21 | 22 | // Creating new folder 23 | var createNewFolder = await testContext.Folders 24 | .CreateFolderAsync(myFolderName, documentsFolder?.Id) 25 | .ConfigureAwait(false); 26 | 27 | Assert.IsNotNull(createNewFolder.Id); 28 | 29 | // Check if new folder exists 30 | var checkNewFolderExists = await testContext.Folders 31 | .GetFolderAsync(documentsFolder?.Id, new GetFolderOptions {IncludeDocumentsSubfolder = false}) 32 | .ConfigureAwait(false); 33 | 34 | var myFolder = checkNewFolderExists.Folders.FirstOrDefault(f => f.Name == myFolderName); 35 | Assert.AreEqual(myFolderName, myFolder?.Name); 36 | 37 | // clean up 38 | await testContext.Folders.DeleteFolderAsync(myFolder?.Id).ConfigureAwait(false); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Folders/DeleteFolder.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class FolderExamples 9 | { 10 | [TestMethod] 11 | public async Task DeleteFolderAsync() 12 | { 13 | // Create some folder for test inside the Documents folder 14 | var root = await testContext.Folders.GetAllFoldersAsync().ConfigureAwait(false); 15 | var documentsFolder = root.Folders.FirstOrDefault(f => f.Name == "Documents"); 16 | var folderToDelete = await testContext.Folders 17 | .CreateFolderAsync("DeleteMe", documentsFolder?.Id) 18 | .ConfigureAwait(false); 19 | 20 | // Check if test folder exists 21 | var createdFolder = await testContext.Folders 22 | .GetFolderAsync(folderToDelete.Id) 23 | .ConfigureAwait(false); 24 | Assert.AreEqual(folderToDelete.Id, createdFolder.Id); 25 | 26 | // Delete folder 27 | await testContext.Folders.DeleteFolderAsync(folderToDelete.Id).ConfigureAwait(false); 28 | 29 | // Check if test folder has been deleted 30 | var folders = await testContext.Folders 31 | .GetFolderAsync(documentsFolder?.Id, new GetFolderOptions {IncludeDocumentsSubfolder = false}) 32 | .ConfigureAwait(false); 33 | 34 | Assert.IsFalse(folders.Folders.Any(f => f.Name == "DeleteMe")); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Folders/GetAllFolders.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class FolderExamples 9 | { 10 | [TestMethod] 11 | public async Task GetAllFoldersAsync() 12 | { 13 | // get all folders 14 | var folders = await testContext.Folders 15 | .GetAllFoldersAsync() 16 | .ConfigureAwait(false); 17 | 18 | // check if the root folder contains the default folders 19 | Assert.IsInstanceOfType(folders, typeof(SignNowFolders)); 20 | Assert.AreEqual("Root", folders.Name); 21 | Assert.IsTrue(folders.SystemFolder); 22 | 23 | Assert.IsTrue(folders.Folders.Any(f => f.Name == "Documents")); 24 | Assert.IsTrue(folders.Folders.Any(f => f.Name == "Archive")); 25 | Assert.IsTrue(folders.Folders.Any(f => f.Name == "Templates")); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Folders/GetFolder.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | using SignNow.Net.Model.Requests; 6 | using SignNow.Net.Model.Requests.GetFolderQuery; 7 | 8 | namespace SignNow.Net.Examples 9 | { 10 | public partial class FolderExamples 11 | { 12 | [TestMethod] 13 | public async Task GetFolderAsync() 14 | { 15 | // Get all folders 16 | var folders = await testContext.Folders.GetAllFoldersAsync().ConfigureAwait(false); 17 | 18 | // Get folderId of the "Documents" folder 19 | var folderId = folders.Folders.FirstOrDefault(f => f.Name == "Documents")?.Id; 20 | 21 | var filterBySigningStatus = new GetFolderOptions 22 | { 23 | Filters = new FolderFilters(SigningStatus.Pending) 24 | }; 25 | 26 | // Get all details of a specific folder including a list of all documents in that folder 27 | var folder = await testContext.Folders 28 | .GetFolderAsync(folderId, filterBySigningStatus) 29 | .ConfigureAwait(false); 30 | 31 | // Check if folder contains only pending documents 32 | Assert.IsTrue(folders.Documents.All(d => d.Status == DocumentStatus.Pending)); 33 | Assert.AreEqual(folders.TotalDocuments, folders.Documents.Count); 34 | Assert.IsTrue(folder.SystemFolder); 35 | Assert.AreEqual(folderId, folder.Id); 36 | Assert.AreEqual(folders.Id, folder.ParentId); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Folders/RenameFolder.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace SignNow.Net.Examples 6 | { 7 | public partial class FolderExamples 8 | { 9 | [TestMethod] 10 | public async Task RenameFolderAsync() 11 | { 12 | // Creates folder inside Documents folder for test 13 | var root = await testContext.Folders.GetAllFoldersAsync().ConfigureAwait(false); 14 | 15 | // Get Documents folder 16 | var documentsFolder = root.Folders.FirstOrDefault(f => f.Name == "Documents"); 17 | 18 | // create a folder for test 19 | var folderForRename = await testContext.Folders 20 | .CreateFolderAsync("noname", documentsFolder?.Id) 21 | .ConfigureAwait(false); 22 | 23 | // Rename previously created folder 24 | var renameFolder = await testContext.Folders 25 | .RenameFolderAsync("ItsRenamedFolder", folderForRename.Id) 26 | .ConfigureAwait(false); 27 | 28 | var renamed = await testContext.Folders.GetFolderAsync(renameFolder.Id).ConfigureAwait(false); 29 | 30 | // Check if folder renamed 31 | Assert.AreEqual("ItsRenamedFolder", renamed.Name); 32 | Assert.AreEqual(folderForRename.Id, renamed.Id); 33 | 34 | // Finally - delete test folder 35 | await testContext.Folders.DeleteFolderAsync(renamed.Id).ConfigureAwait(false); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/OAuth2/GenerateAccessToken.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Service; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | [TestClass] 9 | public partial class OAuth2Examples : ExamplesBase 10 | { 11 | /// 12 | /// An example of obtaining an access token via OAuth 2.0 service. 13 | /// 14 | [TestMethod] 15 | public async Task GenerateAccessTokenAsync() 16 | { 17 | var clientId = credentials.ClientId; 18 | var clientSecret = credentials.ClientSecret; 19 | 20 | var userLogin = credentials.Login; 21 | var userPassword = credentials.Password; 22 | 23 | var oauth = new OAuth2Service(ApiBaseUrl, clientId, clientSecret) 24 | { 25 | ExpirationTime = 60 26 | }; 27 | 28 | var response = await oauth.GetTokenAsync(userLogin, userPassword, Scope.All) 29 | .ConfigureAwait(false); 30 | 31 | Assert.IsNotNull(response); 32 | Assert.IsFalse(string.IsNullOrEmpty(response.AccessToken)); 33 | Assert.IsFalse(string.IsNullOrEmpty(response.RefreshToken)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/OAuth2/RefreshAccessToken.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Service; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class OAuth2Examples 9 | { 10 | /// 11 | /// Refresh access token example 12 | /// 13 | [TestMethod] 14 | public async Task RefreshAccessTokenAsync() 15 | { 16 | var oauth = new OAuth2Service(ApiBaseUrl, credentials.ClientId, credentials.ClientSecret); 17 | 18 | // Get a valid token 19 | var validToken = await oauth.GetTokenAsync(credentials.Login, credentials.Password, Scope.All) 20 | .ConfigureAwait(false); 21 | 22 | // Refresh the token 23 | var refreshedToken = await oauth.RefreshTokenAsync(validToken) 24 | .ConfigureAwait(false); 25 | 26 | Assert.AreNotEqual(refreshedToken, validToken); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/OAuth2/VerifyAccessToken.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Service; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class OAuth2Examples 9 | { 10 | /// 11 | /// An example of validating an access token via OAuth 2.0 service. 12 | /// 13 | [TestMethod] 14 | public async Task VerifyAccessTokenAsync() 15 | { 16 | var oauth = new OAuth2Service(ApiBaseUrl, credentials.Login, credentials.Password); 17 | 18 | var dummyToken = new Token 19 | { 20 | AccessToken = "dummyAccessToken", 21 | AppToken = "dummyAppToken", 22 | ExpiresIn = 100, 23 | Scope = "*", 24 | TokenType = TokenType.Bearer 25 | }; 26 | 27 | var dummyTokenResponse = await oauth.ValidateTokenAsync(dummyToken) 28 | .ConfigureAwait(false); 29 | 30 | Assert.IsFalse(dummyTokenResponse); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/SignNow.Net.Examples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | net7.0 6 | 7 | false 8 | 9 | 10 | 11 | 1591 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Template/CreateDocumentFromTheTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace SignNow.Net.Examples 6 | { 7 | [TestClass] 8 | public partial class TemplateExamples: ExamplesBase 9 | { 10 | [TestMethod] 11 | public async Task CreateDocumentFromTemplateAsync() 12 | { 13 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 14 | 15 | // Upload a document with a signature field 16 | var testDocument = await testContext.Documents 17 | .UploadDocumentWithFieldExtractAsync(fileStream, "DocumentWithSignatureTextTag.pdf") 18 | .ConfigureAwait(false); 19 | 20 | // Create a template from the uploaded document 21 | var template = await testContext.Documents 22 | .CreateTemplateFromDocumentAsync(testDocument.Id, "TemplateName") 23 | .ConfigureAwait(false); 24 | 25 | // Creates a new document copy out of template 26 | var documentName = "Document Name"; 27 | var result = await testContext.Documents 28 | .CreateDocumentFromTemplateAsync(template.Id, documentName) 29 | .ConfigureAwait(false); 30 | 31 | // Get the new document created from template 32 | var document = await testContext.Documents 33 | .GetDocumentAsync(result.Id) 34 | .ConfigureAwait(false); 35 | 36 | // Check that the document is not a template 37 | Assert.IsNotNull(document?.Id); 38 | Assert.IsFalse(document.IsTemplate); 39 | Assert.AreEqual(documentName, document.Name); 40 | 41 | // clean up 42 | await testContext.Documents.DeleteDocumentAsync(document.Id).ConfigureAwait(false); 43 | await testContext.Documents.DeleteDocumentAsync(template.Id).ConfigureAwait(false); 44 | DeleteTestDocument(testDocument?.Id); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Template/CreateTemplateFromTheDocument.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace SignNow.Net.Examples 6 | { 7 | public partial class TemplateExamples 8 | { 9 | [TestMethod] 10 | public async Task CreateTemplateFromDocumentAsync() 11 | { 12 | await using var fileStream = File.OpenRead(PdfWithSignatureField); 13 | 14 | // Upload a document with a signature field 15 | var document = await testContext.Documents 16 | .UploadDocumentWithFieldExtractAsync(fileStream, "DocumentWithSignatureTextTag.pdf") 17 | .ConfigureAwait(false); 18 | 19 | // create a template from the uploaded document 20 | const string templateName = "Template Name"; 21 | var result = await testContext.Documents 22 | .CreateTemplateFromDocumentAsync(document?.Id, templateName) 23 | .ConfigureAwait(false); 24 | 25 | // Get the new template created from the document 26 | var template = await testContext.Documents 27 | .GetDocumentAsync(result.Id) 28 | .ConfigureAwait(false); 29 | 30 | // Check that the document is a template 31 | Assert.IsNotNull(template?.Id); 32 | Assert.AreEqual(templateName, template.Name); 33 | Assert.IsTrue(template.IsTemplate); 34 | 35 | // clean up 36 | await testContext.Documents.DeleteDocumentAsync(template.Id).ConfigureAwait(false); 37 | DeleteTestDocument(document?.Id); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/TestExamples/ComplexTags.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signnow/SignNow.NET/7122c316be1fbcc019876f87da27f85c4af01522/SignNow.Net.Examples/TestExamples/ComplexTags.pdf -------------------------------------------------------------------------------- /SignNow.Net.Examples/TestExamples/DocumentWithSignatureFieldTag.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signnow/SignNow.NET/7122c316be1fbcc019876f87da27f85c4af01522/SignNow.Net.Examples/TestExamples/DocumentWithSignatureFieldTag.pdf -------------------------------------------------------------------------------- /SignNow.Net.Examples/TestExamples/SignAndDate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signnow/SignNow.NET/7122c316be1fbcc019876f87da27f85c4af01522/SignNow.Net.Examples/TestExamples/SignAndDate.pdf -------------------------------------------------------------------------------- /SignNow.Net.Examples/Users/CreateSignNowUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | [TestClass] 9 | public partial class UserExamples : ExamplesBase 10 | { 11 | [TestMethod] 12 | public async Task CreateSignNowUserAsync() 13 | { 14 | var timestamp = (long)(DateTime.Now - UnixEpoch).TotalSeconds; 15 | var email = $"signnow.tutorial+create_user_test{timestamp}@gmail.com"; 16 | 17 | var userRequest = new CreateUserOptions 18 | { 19 | Email = email, 20 | FirstName = "John", 21 | LastName = "Wick", 22 | Password = "password" 23 | }; 24 | 25 | // Create a new user 26 | var createUserResponse = await testContext.Users 27 | .CreateUserAsync(userRequest) 28 | .ConfigureAwait(false); 29 | 30 | // Check if the user was created and not verified 31 | Assert.AreEqual(email, createUserResponse.Email); 32 | Assert.IsFalse(createUserResponse.Verified); 33 | 34 | // Finally - send verification email to User 35 | await testContext.Users 36 | .SendVerificationEmailAsync(email) 37 | .ConfigureAwait(false); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Users/GetUserDocuments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class UserExamples 9 | { 10 | [TestMethod] 11 | public async Task GetUserDocumentsAsync() 12 | { 13 | // Get user documents, first 25 documents 14 | var signNowDocuments = await testContext.Users 15 | .GetUserDocumentsAsync(perPage:25) 16 | .ConfigureAwait(false); 17 | 18 | // Check if the documents are owned by the user 19 | var userDocuments = signNowDocuments.ToList(); 20 | foreach (var document in userDocuments) 21 | { 22 | Assert.AreEqual(credentials.Login, document.Owner); 23 | } 24 | 25 | Assert.IsNotNull(userDocuments.Count); 26 | Console.WriteLine($@"Total modified documents: {userDocuments.Count}"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net.Examples/Users/GetUserModifiedDocuments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace SignNow.Net.Examples 7 | { 8 | public partial class UserExamples 9 | { 10 | [TestMethod] 11 | public async Task GetUserModifiedDocumentsAsync() 12 | { 13 | // get user modified documents 14 | var signNowDocuments = await testContext.Users 15 | .GetModifiedDocumentsAsync(perPage:25) 16 | .ConfigureAwait(false); 17 | 18 | // check if user is the owner of the modified documents 19 | var modifiedDocuments = signNowDocuments.ToList(); 20 | foreach (var document in modifiedDocuments) 21 | { 22 | Assert.AreEqual(credentials.Login, document.Owner); 23 | } 24 | 25 | Assert.IsNotNull(modifiedDocuments.Count); 26 | Console.WriteLine($@"Total modified documents: {modifiedDocuments.Count}"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net.Test/AcceptanceTests/DocumentServiceTest.CreateSigningLink.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System; 3 | using System.Globalization; 4 | using System.Threading.Tasks; 5 | using SignNow.Net.Exceptions; 6 | 7 | namespace AcceptanceTests 8 | { 9 | public partial class DocumentServiceTest 10 | { 11 | [TestMethod] 12 | public async Task SigningLinkCreatedSuccessfully() 13 | { 14 | var signingLinks = await SignNowTestContext.Documents 15 | .CreateSigningLinkAsync(TestPdfDocumentIdWithFields) 16 | .ConfigureAwait(false); 17 | 18 | Assert.IsNotNull(signingLinks.Url); 19 | Assert.IsNotNull(signingLinks.AnonymousUrl); 20 | } 21 | 22 | [TestMethod] 23 | public async Task ThrowsExceptionForWrongDocumentId() 24 | { 25 | var exception = await Assert 26 | .ThrowsExceptionAsync( 27 | async () => await SignNowTestContext.Documents 28 | .CreateSigningLinkAsync("Some Wrong Document Id") 29 | .ConfigureAwait(false)) 30 | .ConfigureAwait(false); 31 | 32 | var expected = string 33 | .Format(CultureInfo.CurrentCulture, ExceptionMessages.InvalidFormatOfId, "Some Wrong Document Id"); 34 | 35 | StringAssert.Contains(exception.Message, expected); 36 | Assert.AreEqual("Some Wrong Document Id", exception.ParamName); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net.Test/AcceptanceTests/DocumentServiceTest.Delete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using System.Threading.Tasks; 5 | using SignNow.Net.Exceptions; 6 | 7 | namespace AcceptanceTests 8 | { 9 | public partial class DocumentServiceTest 10 | { 11 | [TestMethod] 12 | public void DocumentDeletingSuccess() 13 | { 14 | DisposableDocumentId = UploadTestDocument(PdfFilePath); 15 | 16 | var deleteResponse = SignNowTestContext.Documents.DeleteDocumentAsync(DisposableDocumentId); 17 | Task.WaitAll(deleteResponse); 18 | 19 | Assert.IsFalse( 20 | deleteResponse.IsFaulted, 21 | "Document Delete result has error, status code is not Successful"); 22 | } 23 | 24 | [TestMethod] 25 | public async Task CannotDeleteDocumentWithWrongId() 26 | { 27 | var documentId = "test"; 28 | 29 | var exception = await Assert 30 | .ThrowsExceptionAsync( 31 | async () => await SignNowTestContext.Documents.DeleteDocumentAsync(documentId).ConfigureAwait(false)) 32 | .ConfigureAwait(false); 33 | 34 | StringAssert.Contains(exception.Message, string.Format(CultureInfo.CurrentCulture, ExceptionMessages.InvalidFormatOfId, documentId)); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net.Test/AcceptanceTests/DocumentServiceTest.Download.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model; 4 | using UnitTests; 5 | 6 | namespace AcceptanceTests 7 | { 8 | public partial class DocumentServiceTest 9 | { 10 | [DataTestMethod] 11 | [DataRow(DownloadType.PdfOriginal, ".pdf")] 12 | [DataRow(DownloadType.PdfCollapsed, ".pdf")] 13 | [DataRow(DownloadType.PdfWithHistory, ".pdf")] 14 | [DataRow(DownloadType.ZipCollapsed, ".zip")] 15 | public async Task DownloadDocumentAsSpecifiedType(DownloadType downloadType, string expectedType) 16 | { 17 | var downloadResponse = await SignNowTestContext.Documents 18 | .DownloadDocumentAsync(TestPdfDocumentId, downloadType) 19 | .ConfigureAwait(false); 20 | 21 | StringAssert.Contains(downloadResponse.Filename, "DocumentUpload", "Wrong Document name"); 22 | StringAssert.Contains(downloadResponse.Filename, expectedType, "Wrong Document type"); 23 | 24 | if (downloadType == DownloadType.ZipCollapsed) 25 | { 26 | Assert.That.StreamIsZip(downloadResponse.Document); 27 | } 28 | else 29 | { 30 | Assert.That.StreamIsPdf(downloadResponse.Document); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SignNow.Net.Test/AcceptanceTests/SignNowExceptionTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using SignNow.Net.Exceptions; 6 | using UnitTests; 7 | 8 | namespace AcceptanceTests 9 | { 10 | [TestClass] 11 | public class SignNowExceptionTest : AuthorizedApiTestBase 12 | { 13 | [TestMethod] 14 | public async Task ExceptionHandlingTest() 15 | { 16 | var documentId = "mstestSignNowDotNetSDK000000000000000000"; 17 | var errorMessage = "Unable to find a route to match the URI: document/" + documentId; 18 | var rawErrorResponse = "{\"404\":\"Unable to find a route to match the URI: document\\/" + documentId + "\"}"; 19 | 20 | var exception = await Assert.ThrowsExceptionAsync( 21 | async () => await SignNowTestContext.Documents 22 | .DeleteDocumentAsync(documentId) 23 | .ConfigureAwait(false)) 24 | .ConfigureAwait(false); 25 | 26 | Assert.AreEqual(errorMessage, exception.Message); 27 | Assert.AreEqual(HttpStatusCode.NotFound, exception.HttpStatusCode); 28 | Assert.AreEqual(rawErrorResponse, exception.RawResponse); 29 | Assert.IsTrue(exception.RawHeaders 30 | .ToDictionary(x => x.Key, x => x.Value) 31 | .ContainsKey("Connection")); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Constants/ErrorMessages.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Test.Constants 2 | { 3 | /// 4 | /// String constants and error messages for unit-tests. 5 | /// 6 | public static class ErrorMessages 7 | { 8 | public static readonly string InvalidFileType = "Invalid file type."; 9 | 10 | /// 11 | /// Starts string message for Exceptions with nullable param: `Value cannot be null.` 12 | /// 13 | public static readonly string ValueCannotBeNull = "Value cannot be null."; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Context/CredentialLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace SignNow.Net.Test.Context 5 | { 6 | public class CredentialLoader 7 | { 8 | /// 9 | /// Directory where is located file with credentials. 10 | /// 11 | public static string CredentialsDirectory { get; set; } = "./../../../../"; 12 | 13 | private readonly ICredentialProvider credentialProvider; 14 | 15 | public CredentialLoader(Uri credentialsTarget, string basePath = default) : this( 16 | new JsonFileCredentialProvider(GetCredentialsFilePath(credentialsTarget))) 17 | { 18 | if (!String.IsNullOrWhiteSpace(basePath)) 19 | CredentialsDirectory = basePath.Replace('/', Path.DirectorySeparatorChar); 20 | } 21 | 22 | public CredentialLoader(ICredentialProvider credentialProvider) 23 | { 24 | this.credentialProvider = credentialProvider; 25 | } 26 | 27 | public CredentialModel GetCredentials() 28 | { 29 | return credentialProvider.GetCredential(); 30 | } 31 | 32 | private static string GetCredentialsFileName(Uri credentialsTarget) 33 | { 34 | return $"{credentialsTarget.Host}.json"; 35 | } 36 | 37 | private static string GetCredentialsFilePath(Uri credentialsTarget) 38 | { 39 | return Path.GetFullPath($"{CredentialsDirectory}{GetCredentialsFileName(credentialsTarget)}"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Context/CredentialModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Test.Context 4 | { 5 | public class CredentialModel 6 | { 7 | [JsonProperty("login")] 8 | public string Login { get; set; } 9 | 10 | [JsonProperty("password")] 11 | public string Password { get; set; } 12 | 13 | [JsonProperty("client_id")] 14 | public string ClientId { get; set; } 15 | 16 | [JsonProperty("client_secret")] 17 | public string ClientSecret { get; set; } 18 | 19 | [JsonProperty("authorization_code", NullValueHandling = NullValueHandling.Ignore)] 20 | public string AuthorizationCode { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Context/ICredentialProvider.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Test.Context 2 | { 3 | public interface ICredentialProvider 4 | { 5 | CredentialModel GetCredential(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Context/JsonCredentialProvider.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace SignNow.Net.Test.Context 7 | { 8 | class JsonCredentialProvider : ICredentialProvider 9 | { 10 | private readonly string jsonString; 11 | public JsonCredentialProvider(string jsonString) 12 | { 13 | this.jsonString = jsonString; 14 | } 15 | 16 | public CredentialModel GetCredential() 17 | { 18 | try 19 | { 20 | return JsonConvert.DeserializeObject(jsonString); 21 | } 22 | catch (JsonSerializationException ex) 23 | { 24 | throw new InvalidOperationException("Unable to parse values provided. You have to specify json string with login and password text properties in the constructor of this class", ex); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Context/JsonFileCredentialProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace SignNow.Net.Test.Context 7 | { 8 | class JsonFileCredentialProvider : ICredentialProvider 9 | { 10 | private readonly string jsonFilePath; 11 | public string JsonFilePath => jsonFilePath; 12 | public JsonFileCredentialProvider(string jsonFilePath) 13 | { 14 | this.jsonFilePath = jsonFilePath; 15 | } 16 | 17 | public CredentialModel GetCredential() 18 | { 19 | if (!File.Exists(JsonFilePath)) 20 | { 21 | throw new InvalidOperationException($"Unable to locate file {JsonFilePath}. {GetUsageHint(jsonFilePath)}"); 22 | } 23 | 24 | var jsonCredProvider = new JsonCredentialProvider(File.ReadAllText(JsonFilePath)); 25 | try 26 | { 27 | return jsonCredProvider.GetCredential(); 28 | } 29 | catch (InvalidOperationException ex) 30 | { 31 | throw new InvalidOperationException($"Wrong file format: {ex.Message}. {GetUsageHint(jsonFilePath)}", ex); 32 | } 33 | } 34 | 35 | private static string GetUsageHint(string filePath) 36 | { 37 | return $"To use this class you have to create JSON file {filePath} " 38 | + "with single object {{'login':'login string','password':'password string','client_id':'app client id','client_secret':'app client secret'}}"; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SignNow.Net.Test/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | false 6 | 7 | 8 | 9 | 10 | true 11 | opencover,json 12 | $(MSBuildProjectDirectory)/bin/$(Configuration)/$(TargetFramework)/ 13 | $(MSBuildProjectDirectory)/bin/$(Configuration)/$(TargetFramework)/coverage.$(TargetFramework).json 14 | Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute 15 | 16 | 17 | -------------------------------------------------------------------------------- /SignNow.Net.Test/FeatureTests/DotnetTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System; 3 | using System.Globalization; 4 | using System.IO; 5 | using System.Net.Http; 6 | using System.Text; 7 | 8 | namespace FeatureTests 9 | { 10 | [TestClass] 11 | public class DotnetTest 12 | { 13 | [TestMethod] 14 | public void StreamContentIsDisposedInMultipartFormDataContent() 15 | { 16 | var streamContent = new MemoryStream(Encoding.UTF8.GetBytes("Hello world!")); 17 | var multipartContent = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); 18 | multipartContent.Add(new StreamContent(streamContent), "file", "upload.pdf"); 19 | 20 | HttpContent content = multipartContent; 21 | content.Dispose(); 22 | 23 | try 24 | { 25 | var result = multipartContent.ReadAsStringAsync().Result; 26 | Assert.Fail(result); 27 | } 28 | catch (ObjectDisposedException) 29 | { 30 | } 31 | try 32 | { 33 | var result = streamContent.Length; 34 | Assert.Fail("Underline stream content is not disposed! Content length = " + result.ToString(CultureInfo.InvariantCulture)); 35 | } 36 | catch (ObjectDisposedException) 37 | { 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SignNow.Net.Test/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppression either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Microsoft.Naming", "CA1707:Identifiers should not contain underscores", Scope = "module")] 9 | 10 | // Suppression for various Mock usage 11 | [assembly: SuppressMessage("Microsoft.Usage", "CA1801:Review unused parameters.", Scope = "module")] 12 | [assembly: SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] 13 | 14 | // Suppression for string messages in tests 15 | [assembly: SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters")] 16 | [assembly: SuppressMessage("Microsoft.Globalization", "CA1304:Specify CultureInfo")] 17 | [assembly: SuppressMessage("Microsoft.Globalization", "CA1305:Specify IFormatProvider")] 18 | [assembly: SuppressMessage("Microsoft.Globalization", "CA1307:Specify StringComparison for clarity")] 19 | [assembly: SuppressMessage("Microsoft.Globalization", "CA1308:Normalize strings to uppercase")] 20 | 21 | [assembly: SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")] 22 | [assembly: SuppressMessage("Microsoft.Design", "CA1054:URI parameters should not be strings")] 23 | -------------------------------------------------------------------------------- /SignNow.Net.Test/SignNow.Net.Test.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  6 | True 7 | 8 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/Documents/DocumentUpload.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signnow/SignNow.NET/7122c316be1fbcc019876f87da27f85c4af01522/SignNow.Net.Test/TestData/Documents/DocumentUpload.pdf -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/Documents/DocumentUpload.txt: -------------------------------------------------------------------------------- 1 | This is test form {{t:t;r:n;o:"Signer 1";}}. -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/EditFields/TextFieldFaker.cs: -------------------------------------------------------------------------------- 1 | using Bogus; 2 | using SignNow.Net.Model.EditFields; 3 | 4 | namespace SignNow.Net.Test.FakeModels.EditFields 5 | { 6 | /// 7 | /// Faker 8 | /// 9 | internal class TextFieldFaker : Faker 10 | { 11 | /// 12 | /// Creates new instance of fake object. 13 | /// 14 | /// 15 | /// This example shows Json representation. 16 | /// 17 | /// { 18 | /// "page_number": 1, 19 | /// "type": "text", 20 | /// "name": "Text_1", 21 | /// "role": "Signer 1", 22 | /// "required": false, 23 | /// "x": 992, 24 | /// "y": 674, 25 | /// "width": 463, 26 | /// "height": 578, 27 | /// "prefilled_text": "labore", 28 | /// "label": "Text_1_Label", 29 | /// } 30 | /// 31 | /// 32 | public TextFieldFaker() 33 | { 34 | Rules((f, o) => 35 | { 36 | o.PageNumber = f.IndexFaker + 1; 37 | o.Name = $"Text_{f.IndexFaker + 1}"; 38 | o.Role = $"Signer {f.IndexFaker + 1}"; 39 | o.Required = f.Random.Bool(); 40 | o.X = f.Random.Int(0, 1024); 41 | o.Y = f.Random.Int(0, 1024); 42 | o.Width = f.Random.Int(0, 1024); 43 | o.Height = f.Random.Int(0, 1024); 44 | o.PrefilledText = f.Lorem.Word(); 45 | o.Label = $"{o.Name}_Label"; 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/EmbeddedInviteFaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Bogus; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace SignNow.Net.Test.FakeModels 7 | { 8 | /// 9 | /// Faker for 10 | /// 11 | public class EmbeddedInviteFaker : Faker 12 | { 13 | /// 14 | /// Faker 15 | /// 16 | /// 17 | /// This example shows Json representation. 18 | /// 19 | /// { 20 | /// "email": "Jesus_Monahan@gmail.com", 21 | /// "language": "en", 22 | /// "auth_method": "none", 23 | /// "first_name": "Jesus", 24 | /// "last_name": "Monahan", 25 | /// "prefill_signature_name": "Jesus Monahan prefill signature", 26 | /// "force_new_signature": "1", 27 | /// "redirect_uri": "https://signnow.com", 28 | /// "decline_redirect_uri": "https://signnow.com", 29 | /// "redirect_target": "self", 30 | /// "role_id": "c376990ca7e1e84ea7f6e252144e435f314bb63b", 31 | /// "order": 1 32 | /// } 33 | /// 34 | /// 35 | public EmbeddedInviteFaker() 36 | { 37 | Rules((f, o) => 38 | { 39 | o.Email = f.Internet.Email(); 40 | o.Language = f.PickRandom(); 41 | o.AuthMethod = f.PickRandom(); 42 | o.Firstname = f.Person.FirstName; 43 | o.Lastname = f.Person.LastName; 44 | o.PrefillSignatureName = $"{f.Person.FirstName} {f.Person.LastName} prefill signature"; 45 | o.ForceNewSignature = f.Random.Bool(); 46 | o.RedirectUrl = new Uri(f.Internet.Url()); 47 | o.DeclineRedirectUrl = new Uri(f.Internet.Url()); 48 | o.RedirectTarget = f.PickRandom(); 49 | o.RoleId = f.Random.Hash(40); 50 | o.SigningOrder = (uint)f.Random.Number(1, 10); 51 | }); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/FieldInviteFaker.cs: -------------------------------------------------------------------------------- 1 | using Bogus; 2 | using SignNow.Net.Model; 3 | 4 | namespace SignNow.Net.Test.FakeModels 5 | { 6 | /// 7 | /// Faker 8 | /// 9 | public class FieldInviteFaker : Faker 10 | { 11 | /// 12 | /// Creates new instance of faker object. 13 | /// 14 | /// 15 | /// This example shows Json representation. 16 | /// 17 | /// { 18 | /// "id": "279f2bee6200ac33d67778566b4bafd01a589296", 19 | /// "status": "Skipped", 20 | /// "role": "Signer 1", 21 | /// "role_id": "b6aa248f9599317e49a07148a0e5318db42ee914", 22 | /// "email": "Lacy60@yahoo.com", 23 | /// "created": 1580844946, 24 | /// "updated": 1580841391, 25 | /// "expiration_time": 1580848760, 26 | /// "is_embedded": false 27 | /// } 28 | /// 29 | /// 30 | public FieldInviteFaker() 31 | { 32 | Rules((f, o) => 33 | { 34 | o.Id = f.Random.Hash(40); 35 | o.Status = f.PickRandom(); 36 | o.RoleName = $"Signer {f.IndexFaker + 1}"; 37 | o.RoleId = f.Random.Hash(40); 38 | o.SignerEmail = f.Internet.Email(); 39 | o.Created = f.Date.Recent().ToUniversalTime(); 40 | o.Updated = f.Date.Recent().ToUniversalTime(); 41 | o.ExpiredOn = f.Date.Recent().ToUniversalTime(); 42 | o.IsEmbedded = false; 43 | }); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/FreeFormInviteFaker.cs: -------------------------------------------------------------------------------- 1 | using Bogus; 2 | using SignNow.Net.Model; 3 | 4 | namespace SignNow.Net.Test.FakeModels 5 | { 6 | /// 7 | /// Faker for 8 | /// 9 | public class FreeformInviteFaker : Faker 10 | { 11 | /// 12 | /// Creates new instance of faker object. 13 | /// 14 | /// 15 | /// This example shows Json representation. 16 | /// 17 | /// { 18 | /// "id": "279f2bee6200ac33d67778566b4bafd01a589296", 19 | /// "user_id": "b6aa248f9599317e49a07148a0e5318db42ee914", 20 | /// "signature_id": "9640e7a2c6d2fca9282a6e24e3b5319a07718b34", 21 | /// "created": 1580844946, 22 | /// "originator_email": "Lacy60@yahoo.com", 23 | /// "signer_email": "Bernadine46@yahoo.com", 24 | /// "canceled": "1" 25 | /// } 26 | /// 27 | /// 28 | public FreeformInviteFaker() 29 | { 30 | Rules((f, o) => 31 | { 32 | o.Id = f.Random.Hash(40); 33 | o.UserId = f.Random.Hash(40); 34 | o.SignatureId = f.Random.Hash(40); 35 | o.Created = f.Date.Recent().ToUniversalTime(); 36 | o.Owner = f.Internet.Email(); 37 | o.SignerEmail = f.Internet.Email(); 38 | o.IsCanceled = f.Random.Bool(); 39 | }); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/RoleFaker.cs: -------------------------------------------------------------------------------- 1 | using Bogus; 2 | using SignNow.Net.Model; 3 | 4 | namespace SignNow.Net.Test.FakeModels 5 | { 6 | /// 7 | /// Faker 8 | /// 9 | public class RoleFaker : Faker 10 | { 11 | /// 12 | /// Creates new instance of fake object. 13 | /// 14 | /// 15 | /// This example shows Json representation. 16 | /// 17 | /// { 18 | /// "unique_id": "cd3421c6f5cecb68b826d63d749f87c35e915fe3", 19 | /// "signing_order": 1, 20 | /// "name": "Signer 1" 21 | /// } 22 | /// 23 | /// 24 | public RoleFaker() 25 | { 26 | Rules((f, o) => 27 | { 28 | o.Id = f.Random.Hash(40); 29 | o.Name = $"Signer {f.IndexFaker + 1}"; 30 | o.SigningOrder = f.IndexFaker + 1; 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/ThumbnailFaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Bogus; 3 | using SignNow.Net.Model; 4 | 5 | namespace SignNow.Net.Test.FakeModels 6 | { 7 | /// 8 | /// Fake model for 9 | /// 10 | public class ThumbnailFaker : Faker 11 | { 12 | private const string DefaultThumbnailText = "signNow test"; 13 | 14 | public ThumbnailFaker() 15 | { 16 | Rules((f, o) => 17 | { 18 | o.Small = new Uri(f.Image.PlaceholderUrl(85, 110, DefaultThumbnailText)); 19 | o.Medium = new Uri(f.Image.PlaceholderUrl(340, 440, DefaultThumbnailText)); 20 | o.Large = new Uri(f.Image.PlaceholderUrl(890, 1151, DefaultThumbnailText)); 21 | }); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestData/FakeModels/TokenFaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Bogus; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | using SignNow.Net.Model; 5 | 6 | namespace SignNow.Net.Test.FakeModels 7 | { 8 | /// 9 | /// Faker 10 | /// 11 | public class TokenFaker : Faker 12 | { 13 | /// 14 | /// Creates new instance of fake object. 15 | /// 16 | /// 17 | /// This example shows Json representation. 18 | /// 19 | /// { 20 | /// "expires_in": 2592000, 21 | /// "access_token": "6ee36f633fb6efbfebac4a2a81c273a7186b7f010356b6a899a258bbb3a524bf", 22 | /// "refresh_token": "54559f7eb8c05ce2639e8718dbf45aec760704f91b6ccb6f58efad6d2c8df390", 23 | /// "scope": "*", 24 | /// "token_type": "Bearer", 25 | /// "last_login": 1 26 | /// } 27 | /// 28 | /// 29 | public TokenFaker() 30 | { 31 | Rules((f, o) => 32 | { 33 | o.ExpiresIn = (int)UnixTimeStampConverter.ToUnixTimestamp(DateTime.Now.AddDays(f.Random.Int(1, 30))); 34 | o.AccessToken = f.Random.Hash(64); 35 | o.RefreshToken = f.Random.Hash(64); 36 | o.Scope = f.PickRandom("user", "*"); 37 | o.TokenType = TokenType.Bearer; 38 | o.LastLogin = 1; 39 | o.AppToken = "basic_token"; 40 | } 41 | ); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SignNow.Net.Test/TestUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using Newtonsoft.Json; 5 | 6 | namespace UnitTests 7 | { 8 | public static class TestUtils 9 | { 10 | /// 11 | public static string SerializeToJsonFormatted(object value) 12 | { 13 | return JsonConvert.SerializeObject(value, Formatting.Indented); 14 | } 15 | 16 | /// 17 | public static T DeserializeFromJson(string value) 18 | { 19 | return JsonConvert.DeserializeObject(value); 20 | } 21 | 22 | /// 23 | /// Dumps object as Json to console output 24 | /// 25 | /// any of object 26 | public static void Dump(object value) 27 | { 28 | Console.WriteLine(SerializeToJsonFormatted(value)); 29 | } 30 | 31 | /// 32 | /// Retrieve test case name for `DataTestMethod`. 33 | /// Test name must be a first element in `object`. 34 | /// 35 | /// 36 | /// public static IEnumerable{object[]} FieldContentProvider() 37 | /// { 38 | /// // Test DisplayName | test object 39 | /// yield return new object[] { "radiobutton content test", new RadiobuttonContentFaker().Generate() }; 40 | /// } 41 | /// 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | public static string DynamicDataDisplayName(MethodInfo methodInfo, object[] data) 48 | { 49 | return $"{methodInfo?.Name} {data.FirstOrDefault()?.ToString()}"; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Extensions/ScopeExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Internal.Extensions; 4 | using SignNow.Net.Model; 5 | 6 | namespace UnitTests.Extensions 7 | { 8 | [TestClass] 9 | public class ScopeExtensionsTest 10 | { 11 | [TestMethod] 12 | public void ShouldProperConvertScopeToString() 13 | { 14 | Assert.AreEqual("*", Scope.All.AsString()); 15 | Assert.AreEqual("user", Scope.User.AsString()); 16 | } 17 | 18 | [TestMethod] 19 | public void ThrowsExceptionForWrongScopeConverting() 20 | { 21 | Assert.ThrowsException( 22 | () => 23 | { 24 | var userScope = Scope.User; 25 | var brokenScope = ++userScope; 26 | brokenScope.AsString(); 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Helpers/Converters/Base64ToStringJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | using SignNow.Net.Model.FieldContents; 5 | using SignNow.Net.Test.FakeModels; 6 | 7 | namespace UnitTests.Helpers.Converters 8 | { 9 | [TestClass] 10 | public class StringBase64ToByteArrayJsonConverterTest 11 | { 12 | [TestMethod] 13 | public void ShouldDeserializeBase64AsByteArray() 14 | { 15 | var testJson = JsonConvert.SerializeObject(new SignatureContentFaker().Generate(), Formatting.Indented); 16 | var actualObj = JsonConvert.DeserializeObject(testJson); 17 | 18 | Assert.That.JsonEqual(testJson, actualObj); 19 | } 20 | 21 | [TestMethod] 22 | public void CanConvertUriType() 23 | { 24 | var converter = new StringBase64ToByteArrayJsonConverter(); 25 | Assert.IsTrue(converter.CanConvert(typeof(byte[]))); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Helpers/Converters/BoolToIntJsonConverterTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | using SignNow.Net.Model; 5 | 6 | namespace UnitTests.Helpers.Converters 7 | { 8 | [TestClass] 9 | public class BoolToIntJsonConverterTest 10 | { 11 | [DataTestMethod] 12 | [DataRow(1, true, DisplayName = "Boolean True for integer 1")] 13 | [DataRow(0, false, DisplayName = "Boolean False for integer 0")] 14 | [DataRow(99, false, DisplayName = "False for any integer not equals to 1")] 15 | public void ShouldDeserializeAsBoolean(int jsonParam, bool expected) 16 | { 17 | var json = $@"{{ 18 | ""force_new_signature"": ""{jsonParam}"", 19 | ""email"": ""test@signnow.com"", 20 | ""role"": {{ 21 | ""unique_id"": ""xxx"", 22 | ""signing_order"": 1, 23 | ""name"": ""unit-test"" 24 | }} 25 | }}"; 26 | var obj = JsonConvert.DeserializeObject(json); 27 | 28 | Assert.AreEqual(expected, obj.ForceNewSignature); 29 | } 30 | 31 | [TestMethod] 32 | public void ShouldSerializeBooleanTypeAsInteger() 33 | { 34 | var obj = new SignerOptions("test@signnow.com", new Role()) 35 | { 36 | ForceNewSignature = true, 37 | AllowToReassign = false 38 | }; 39 | 40 | var actual = JsonConvert.SerializeObject(obj); 41 | 42 | StringAssert.Contains(actual, $"\"force_new_signature\":1"); 43 | StringAssert.Contains(actual, $"\"reassign\":0"); 44 | } 45 | 46 | [TestMethod] 47 | public void CanConvertBooleanType() 48 | { 49 | var converter = new BoolToIntJsonConverter(); 50 | Assert.IsTrue(converter.CanConvert(typeof(bool))); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Helpers/Converters/StringToIntJsonConverterTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Internal.Helpers.Converters; 5 | using SignNow.Net.Model; 6 | 7 | namespace UnitTests.Helpers.Converters 8 | { 9 | [TestClass] 10 | public class StringToIntJsonConverterTest 11 | { 12 | [TestMethod] 13 | public void ShouldDeserializeAsInt() 14 | { 15 | var json = $"{{\"page_count\": \"100\"}}"; 16 | var obj = JsonConvert.DeserializeObject(json); 17 | 18 | Assert.AreEqual(100, obj.PageCount); 19 | } 20 | 21 | [TestMethod] 22 | public void ShouldSerializeIntegerNative() 23 | { 24 | var obj = new SignNowDocument 25 | { 26 | PageCount = 100, 27 | Created = DateTime.Now, 28 | Updated = DateTime.Now 29 | }; 30 | 31 | var actual = JsonConvert.SerializeObject(obj); 32 | var expected = $"\"page_count\":100"; 33 | 34 | StringAssert.Contains(actual, expected); 35 | } 36 | 37 | [TestMethod] 38 | public void CanConvertIntType() 39 | { 40 | var converter = new StringToIntJsonConverter(); 41 | Assert.IsTrue(converter.CanConvert(typeof(int))); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Infrastructure/SdkRuntimeTest.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Internal.Infrastructure; 4 | 5 | namespace UnitTests.Infrastructure 6 | { 7 | [TestClass] 8 | public class SdkRuntimeTest 9 | { 10 | [TestMethod] 11 | public void ShouldReturnProperClientName() 12 | { 13 | Assert.AreEqual(SdkRuntime.ClientName, "SignNow .NET API Client"); 14 | } 15 | 16 | [TestMethod] 17 | public void ShouldReturnProperSdkVersion() 18 | { 19 | var pattern = new Regex(@"(?\d+.\d+.\d+.\d+)"); 20 | 21 | StringAssert.Matches(SdkRuntime.Version.ToString(), pattern); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/EditFields/TextFieldTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model.EditFields; 4 | using SignNow.Net.Test.FakeModels.EditFields; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class TextFieldTest 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | var fakeModel = new TextFieldFaker().Generate(); 15 | var jsonFake = TestUtils.SerializeToJsonFormatted(fakeModel); 16 | 17 | var field = TestUtils.DeserializeFromJson(jsonFake); 18 | 19 | Assert.AreEqual(fakeModel.PageNumber, field.PageNumber); 20 | Assert.AreEqual(fakeModel.Label, field.Label); 21 | Assert.AreEqual(fakeModel.Type, field.Type); 22 | Assert.AreEqual(fakeModel.Name, field.Name); 23 | Assert.AreEqual(fakeModel.Role, field.Role); 24 | Assert.AreEqual(fakeModel.Required, field.Required); 25 | Assert.AreEqual(fakeModel.X, field.X); 26 | Assert.AreEqual(fakeModel.Y, field.Y); 27 | Assert.AreEqual(fakeModel.Width, field.Width); 28 | Assert.AreEqual(fakeModel.Height, field.Height); 29 | Assert.AreEqual(fakeModel.PrefilledText, field.PrefilledText); 30 | } 31 | 32 | [TestMethod] 33 | public void ThrowsExceptionForWrongPageNumber() 34 | { 35 | var exception = Assert.ThrowsException( 36 | () => new TextField() { PageNumber = -1 }); 37 | 38 | StringAssert.Contains(exception.Message, "Value cannot be less than 0"); 39 | Assert.AreEqual(exception.ParamName, "PageNumber"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/FieldContentsTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Interfaces; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class FieldContentsTest : SignNowTestBase 10 | { 11 | [TestMethod] 12 | public void GetValueOfFieldContent() 13 | { 14 | var fields = new List() 15 | { 16 | new RadiobuttonContentFaker().Generate(), 17 | new EnumerationContentFaker().Generate(), 18 | new AttachmentContentFaker().Generate(), 19 | new HyperlinkContentFaker().Generate(), 20 | new SignatureContentFaker().Generate(), 21 | new CheckboxContentFaker().Generate(), 22 | new RadioContentFaker().Generate(), 23 | new TextContentFaker().Generate() 24 | }; 25 | 26 | foreach (var fieldContent in fields) 27 | { 28 | Assert.IsNotNull(fieldContent?.GetValue(), nameof(fieldContent) + " is empty\n" + TestUtils.SerializeToJsonFormatted(fieldContent)); 29 | Assert.IsNotNull(fieldContent?.GetValue().ToString()); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/FieldInvitesTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Model; 5 | using SignNow.Net.Test.FakeModels; 6 | 7 | namespace UnitTests.Models 8 | { 9 | [TestClass] 10 | public class FieldInvitesTest 11 | { 12 | [DataTestMethod] 13 | [DataRow(InviteStatus.Created, DisplayName = "Status: created")] 14 | [DataRow(InviteStatus.Pending, DisplayName = "Status: pending")] 15 | [DataRow(InviteStatus.Fulfilled, DisplayName = "Status: fulfilled")] 16 | [DataRow(InviteStatus.Skipped, DisplayName = "Status: skipped")] 17 | public void ShouldDeserializeFromJson(Enum testStatus) 18 | { 19 | var fieldInviteFake = new FieldInviteFaker() 20 | .RuleFor(o => o.Status, testStatus) 21 | .Generate(); 22 | 23 | var expected = JsonConvert.SerializeObject(fieldInviteFake, Formatting.Indented); 24 | 25 | var fieldInvite = JsonConvert.DeserializeObject(expected); 26 | 27 | Assert.That.JsonEqual(expected, fieldInvite); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/FreeformInviteTest.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Model; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class FreeformInviteTest 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | var json = @" 15 | { 16 | 'unique_id': '827a6dc8a83805f5961234304d2166b75ba19cf3', 17 | 'id': '827a6dc8a83805f5961234304d2166b75ba19cf3', 18 | 'user_id': '40204b3344984768bb16d61f8550f8b5edfd719a', 19 | 'created': '1579090178', 20 | 'originator_email': 'owner@signnow.com', 21 | 'signer_email': 'signer@signnow.com', 22 | 'canceled': null, 23 | 'signature_id': '5abc19d0e5b0e77b78fef3202000220f01fea3cf' 24 | }"; 25 | 26 | var response = JsonConvert.DeserializeObject(json); 27 | 28 | Assert.AreEqual("827a6dc8a83805f5961234304d2166b75ba19cf3", response.Id); 29 | Assert.AreEqual("40204b3344984768bb16d61f8550f8b5edfd719a", response.UserId); 30 | Assert.AreEqual("5abc19d0e5b0e77b78fef3202000220f01fea3cf", response.SignatureId); 31 | Assert.AreEqual("2020-01-15 12:09:38Z", response.Created.ToString("u", CultureInfo.CurrentCulture)); 32 | Assert.AreEqual("owner@signnow.com", response.Owner); 33 | Assert.AreEqual("signer@signnow.com", response.SignerEmail); 34 | Assert.IsNull(response.IsCanceled); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/Internal/FieldTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class FieldTest 10 | { 11 | [DataTestMethod] 12 | [DataRow(FieldType.Attachment, DisplayName = "with Attachment fields")] 13 | [DataRow(FieldType.Checkbox, DisplayName = "with Checkbox fields")] 14 | [DataRow(FieldType.Enumeration, DisplayName = "with Enumeration fields")] 15 | [DataRow(FieldType.Hyperlink, DisplayName = "with Hyperlink fields")] 16 | [DataRow(FieldType.Initials, DisplayName = "with Initials fields")] 17 | [DataRow(FieldType.Signature, DisplayName = "with Signature fields")] 18 | [DataRow(FieldType.Text, DisplayName = "with Text fields")] 19 | [DataRow(FieldType.RadioButton, DisplayName = "with Radiobutton fields")] 20 | public void ShouldDeserializeFromJson(FieldType type) 21 | { 22 | var fieldFake = new FieldFaker() 23 | .RuleFor(o => o.Type, type) 24 | .Generate(); 25 | 26 | var expected = JsonConvert.SerializeObject(fieldFake, Formatting.Indented); 27 | var fieldActual = JsonConvert.DeserializeObject(expected); 28 | 29 | Assert.That.JsonEqual(expected, fieldActual); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/RoleTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class RoleTest 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | var fakeRole = new RoleFaker().Generate(); 15 | var jsonFake = JsonConvert.SerializeObject(fakeRole, Formatting.Indented); 16 | 17 | var role = JsonConvert.DeserializeObject(jsonFake); 18 | 19 | Assert.AreEqual(fakeRole.Id, role.Id); 20 | Assert.AreEqual(fakeRole.SigningOrder, role.SigningOrder); 21 | Assert.AreEqual(fakeRole.Name, role.Name); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/SignNowFoldersTest.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Model; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class SignNowFoldersTest : SignNowTestBase 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | var folderJson = @"{ 15 | ""id"": ""e1d8d63ba51c4009ab8241f249c908b0fd5a5e48"", 16 | ""parent_id"": ""a7138ccc971e98080bfa999cc32d4bef4cca51a9"", 17 | ""user_id"": ""40204b3344983368bb16d61f8550f8b5edfd719b"", 18 | ""name"": ""Documents"", 19 | ""created"": ""1566560035"", 20 | ""shared"": false, 21 | ""document_count"": ""150"", 22 | ""template_count"": ""10"", 23 | ""folder_count"": ""20"" 24 | }"; 25 | 26 | var folder = JsonConvert.DeserializeObject(folderJson); 27 | 28 | Assert.AreEqual("e1d8d63ba51c4009ab8241f249c908b0fd5a5e48", folder.Id); 29 | Assert.AreEqual("a7138ccc971e98080bfa999cc32d4bef4cca51a9", folder.ParentId); 30 | Assert.AreEqual("40204b3344983368bb16d61f8550f8b5edfd719b", folder.UserId); 31 | Assert.AreEqual("Documents", folder.Name); 32 | Assert.AreEqual("2019-08-23 11:33:55Z", folder.Created.ToString("u", CultureInfo.CurrentCulture)); 33 | Assert.AreEqual(false, folder.Shared); 34 | Assert.AreEqual(150, folder.TotalDocuments); 35 | Assert.AreEqual(20, folder.TotalFolders); 36 | Assert.AreEqual(10, folder.TotalTemplates); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/SignatureTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model.FieldContents; 4 | using SignNow.Net.Test.FakeModels; 5 | using UnitTests; 6 | 7 | namespace UnitTests.Models 8 | { 9 | [TestClass] 10 | public class SignatureTest 11 | { 12 | [TestMethod] 13 | public void ShouldDeserializeFromJson() 14 | { 15 | var signatureFake = new SignatureContentFaker().Generate(); 16 | var signatureFakeJson = JsonConvert.SerializeObject(signatureFake, Formatting.Indented); 17 | 18 | var signature = JsonConvert.DeserializeObject(signatureFakeJson); 19 | 20 | Assert.That.JsonEqual(signatureFakeJson, signature); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/ThumbnailTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class ThumbnailTest 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | const string Json = @"{ 15 | ""small"": ""https://api.signnow.com/document/a09b26feeba7ce70228afe6290f4445700b6f349/thumbnail?size=small"", 16 | ""medium"":""https://api.signnow.com/document/a09b26feeba7ce70228afe6290f4445700b6f349/thumbnail?size=medium"", 17 | ""large"": ""https://api.signnow.com/document/a09b26feeba7ce70228afe6290f4445700b6f349/thumbnail?size=large"" 18 | }"; 19 | 20 | var actual = JsonConvert.DeserializeObject(Json); 21 | 22 | Assert.AreEqual( 23 | "https://api.signnow.com/document/a09b26feeba7ce70228afe6290f4445700b6f349/thumbnail?size=small", 24 | actual.Small.AbsoluteUri); 25 | Assert.AreEqual("?size=small", actual.Small.Query); 26 | Assert.AreEqual("?size=medium", actual.Medium.Query); 27 | Assert.AreEqual("?size=large", actual.Large.Query); 28 | } 29 | 30 | [TestMethod] 31 | public void ShouldBeSerializable() 32 | { 33 | var model = new ThumbnailFaker().Generate(); 34 | 35 | var actual = JsonConvert.SerializeObject(model); 36 | 37 | StringAssert.Contains(actual, "small"); 38 | StringAssert.Contains(actual, "medium"); 39 | StringAssert.Contains(actual, "large"); 40 | StringAssert.Contains(actual, "https://via.placeholder.com"); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/TokenTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Models 7 | { 8 | [TestClass] 9 | public class TokenTest 10 | { 11 | [TestMethod] 12 | public void ShouldDeserializeFromJson() 13 | { 14 | var fakeToken = new TokenFaker().Generate(); 15 | var fakeJson = JsonConvert.SerializeObject(fakeToken, Formatting.Indented); 16 | 17 | var actual = JsonConvert.DeserializeObject(fakeJson); 18 | var actualJson = JsonConvert.SerializeObject(actual, Formatting.Indented); 19 | 20 | Assert.AreEqual(fakeJson, actualJson); 21 | Assert.AreEqual(fakeToken.AccessToken, actual.AccessToken); 22 | Assert.AreEqual(fakeToken.ExpiresIn, actual.ExpiresIn); 23 | Assert.AreEqual(fakeToken.Scope, actual.Scope); 24 | Assert.AreEqual(fakeToken.TokenType, actual.TokenType); 25 | Assert.AreNotEqual(fakeToken.AppToken, actual.AppToken); 26 | } 27 | 28 | [TestMethod] 29 | public void ShouldGetAuthorizationHeaderValue() 30 | { 31 | var token = new TokenFaker().Generate(); 32 | var expected = $"Bearer {token.AccessToken}"; 33 | 34 | Assert.AreEqual(expected, token.GetAuthorizationHeaderValue()); 35 | 36 | token.TokenType = TokenType.Basic; 37 | token.AppToken = "basic_token"; 38 | Assert.AreEqual("Basic basic_token", token.GetAuthorizationHeaderValue()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Models/UserTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Model; 3 | using SignNow.Net.Test.FakeModels; 4 | 5 | namespace UnitTests.Models 6 | { 7 | [TestClass] 8 | public class UserTest : SignNowTestBase 9 | { 10 | [TestMethod] 11 | public void Deserialization() 12 | { 13 | var userFake = new UserSignNowFaker().Generate(); 14 | var userFakeJson = TestUtils.SerializeToJsonFormatted(userFake); 15 | 16 | var user = TestUtils.DeserializeFromJson(userFakeJson); 17 | 18 | TestUtils.Dump(user); 19 | Assert.That.JsonEqual(userFakeJson, user); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/CopyDocumentGroupRequestTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Internal.Helpers.Converters; 3 | using SignNow.Net.Model.Requests.DocumentGroup; 4 | 5 | namespace UnitTests.Requests 6 | { 7 | [TestClass] 8 | public class CopyDocumentGroupRequestTest 9 | { 10 | [TestMethod] 11 | public void ShouldBeSerializedAsWithDefaultTimestampTest() 12 | { 13 | var request = new CopyDocumentGroupRequest 14 | { 15 | DocumentGroupName = "test name" 16 | }; 17 | var actualTime = UnixTimeStampConverter.ToUnixTimestamp(request.ClientTimestamp); 18 | 19 | var expectedJson = $@"{{""document_group_name"":""test name"",""client_timestamp"":""{actualTime}""}}"; 20 | 21 | Assert.That.JsonEqual(expectedJson, request); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/CreateEmbeddedSigningInviteRequestTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Internal.Requests; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Model.Requests; 5 | using SignNow.Net.Test.FakeModels; 6 | 7 | namespace UnitTests.Requests 8 | { 9 | [TestClass] 10 | public class CreateEmbeddedSigningInviteRequest 11 | { 12 | [TestMethod] 13 | public void ShouldProperCreateJsonRequest() 14 | { 15 | // Creates document with two signers and two filed invites 16 | var document = new SignNowDocumentFaker() 17 | .RuleFor(o => o.Roles, new RoleFaker().Generate(1)) 18 | .Generate(); 19 | 20 | var invite = new EmbeddedSigningInvite(document); 21 | invite.AddEmbeddedSigningInvite( 22 | new EmbeddedInvite 23 | { 24 | Email = "email@gmail.com", 25 | RoleId = document.Roles[0].Id, 26 | SigningOrder = 1, 27 | AuthMethod = EmbeddedAuthType.Mfa 28 | }); 29 | 30 | var embeddedSigningRequest = new EmbeddedSigningRequest(invite); 31 | var jsonBody = embeddedSigningRequest.GetHttpContent().ReadAsStringAsync().Result; 32 | var actualEmbeddedSigning = TestUtils.DeserializeFromJson(jsonBody); 33 | 34 | TestUtils.Dump(embeddedSigningRequest); 35 | 36 | Assert.AreEqual("application/json", embeddedSigningRequest.GetHttpContent().Headers.ContentType?.MediaType); 37 | Assert.IsTrue(jsonBody.Contains("invites")); 38 | Assert.AreEqual((uint)1, actualEmbeddedSigning.Invites[0].SigningOrder); 39 | Assert.AreEqual(document.Roles[0].Id, actualEmbeddedSigning.Invites[0].RoleId); 40 | Assert.AreEqual(EmbeddedAuthType.Mfa, actualEmbeddedSigning.Invites[0].AuthMethod); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/CreateEventSubscriptionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace UnitTests.Requests 7 | { 8 | [TestClass] 9 | public class CreateEventSubscriptionTest 10 | { 11 | [TestMethod] 12 | public void ShouldProperCreateJsonRequest() 13 | { 14 | var option = new CreateEventSubscription( 15 | EventType.DocumentComplete, 16 | "827a6dc8a83805f5961234304d2166b75ba19cf3", 17 | new Uri("http://localhost/callback")) 18 | { 19 | SecretKey = "12345", 20 | Attributes = 21 | { 22 | UseTls12 = true 23 | } 24 | }; 25 | 26 | var actual = $@"{{ 27 | ""action"": ""callback"", 28 | ""event"": ""document.complete"", 29 | ""entity_id"": ""827a6dc8a83805f5961234304d2166b75ba19cf3"", 30 | ""attributes"": {{ 31 | ""delete_access_token"": true, 32 | ""callback"": ""http://localhost/callback"", 33 | ""use_tls_12"": true, 34 | ""docid_queryparam"": false 35 | }}, 36 | ""secret_key"": ""12345"" 37 | }}"; 38 | 39 | Assert.That.JsonEqual(actual, option); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/EmbeddedSigningLinkRequestTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Internal.Requests; 3 | using SignNow.Net.Model.Requests; 4 | using SignNow.Net.Test.FakeModels; 5 | 6 | namespace UnitTests.Requests 7 | { 8 | [TestClass] 9 | public class EmbeddedSigningLinkRequestTest 10 | { 11 | [TestMethod] 12 | public void ShouldProperCreateJsonRequest() 13 | { 14 | var options = new CreateEmbedLinkOptions 15 | { 16 | AuthMethod = EmbeddedAuthType.Email, 17 | FieldInvite = new FieldInviteFaker().Generate(), 18 | LinkExpiration = null 19 | }; 20 | var embedLinkRequest = new EmbeddedSigningLinkRequest(options); 21 | 22 | var jsonBody = embedLinkRequest.GetHttpContent().ReadAsStringAsync().Result; 23 | var actualEmbeddedLink = TestUtils.DeserializeFromJson(jsonBody); 24 | 25 | Assert.AreEqual("application/json", embedLinkRequest.GetHttpContent().Headers.ContentType?.MediaType); 26 | Assert.AreEqual(EmbeddedAuthType.Email, actualEmbeddedLink.AuthMethod); 27 | Assert.AreEqual(null, actualEmbeddedLink.LinkExpiration); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/LimitOffsetOptionsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model.Requests; 4 | 5 | namespace UnitTests.Requests 6 | { 7 | [TestClass] 8 | public class LimitOffsetOptionsTest 9 | { 10 | [TestMethod] 11 | public void BuildQuery() 12 | { 13 | var emptyOptions = new LimitOffsetOptions(); 14 | var fullOptions = new LimitOffsetOptions 15 | { 16 | Limit = 2, 17 | Offset = 3 18 | }; 19 | 20 | Assert.AreEqual(String.Empty, emptyOptions.ToQueryString()); 21 | Assert.AreEqual("limit=2&offset=3", fullOptions.ToQueryString()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/MergeDocumentRequestTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Internal.Requests; 3 | using SignNow.Net.Test.FakeModels; 4 | 5 | namespace UnitTests.Requests 6 | { 7 | [TestClass] 8 | public class MergeDocumentRequestTest : SignNowTestBase 9 | { 10 | [TestMethod] 11 | public void SerializeModel() 12 | { 13 | const string MergedName = "Test_Merged_Document_Name"; 14 | var documents = new SignNowDocumentFaker().Generate(5); 15 | 16 | var request = new MergeDocumentRequest 17 | { 18 | Name = MergedName 19 | }; 20 | request.AddDocuments(documents); 21 | 22 | var serialized = TestUtils.SerializeToJsonFormatted(request); 23 | var requestJ = TestUtils.DeserializeFromJson(serialized); 24 | 25 | Assert.AreEqual(MergedName, requestJ.Name); 26 | Assert.AreEqual(5, requestJ.DocumentIds.Count); 27 | Assert.AreEqual(documents[1].Id, requestJ.DocumentIds[1]); 28 | } 29 | 30 | [TestMethod] 31 | public void CreatesJsonContext() 32 | { 33 | var documents = new SignNowDocumentFaker().Generate(10); 34 | var request = new MergeDocumentRequest 35 | { 36 | Name = "mergedName" 37 | }; 38 | request.AddDocuments(documents); 39 | 40 | var jsonHttpContext = request.GetHttpContent(); 41 | var jsonBody = jsonHttpContext.ReadAsStringAsync().Result; 42 | 43 | Assert.AreEqual("application/json", jsonHttpContext.Headers.ContentType?.MediaType); 44 | Assert.IsTrue(jsonBody.Contains("mergedName")); 45 | Assert.IsTrue(jsonBody.Contains(documents[1].Id)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/MultipartHttpContentTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net.Http; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using SignNow.Net.Model; 5 | using SignNow.Net.Model.ComplexTags; 6 | using SignNow.Net.Model.Requests; 7 | 8 | namespace UnitTests 9 | { 10 | [TestClass] 11 | public class MultipartHttpContentTest : SignNowTestBase 12 | { 13 | [TestMethod] 14 | public void CanGetHttpContent() 15 | { 16 | var testTag = new TextTag() 17 | { 18 | TagName = "Test", 19 | Role = "Signer 1", 20 | Required = true, 21 | Label = "name", 22 | PrefilledText = "enter-the-name", 23 | Width = 100, 24 | Height = 15 25 | }; 26 | var complexTags = new ComplexTextTags(testTag); 27 | 28 | using var testStream = new StreamContent(File.OpenRead(PdfFilePath)); 29 | var multipart = new MultipartHttpContent(testStream.ReadAsStreamAsync().Result, "testFileName", complexTags); 30 | 31 | var httpContent = multipart.GetHttpContent(); 32 | var requestContent = httpContent.ReadAsStringAsync().Result; 33 | 34 | StringAssert.StartsWith(httpContent.Headers.ContentType.ToString(), "multipart/form-data"); 35 | StringAssert.Contains( 36 | requestContent, 37 | "Content-Disposition: form-data; name=file; filename=testFileName; filename*=utf-8''testFileName"); 38 | StringAssert.Contains( 39 | requestContent, 40 | "Content-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name=Tags"); 41 | StringAssert.Contains( 42 | requestContent, 43 | "[{\"type\":\"text\",\"prefilled_text\":\"enter-the-name\",\"label\":\"name\",\"tag_name\":\"Test\",\"role\":\"Signer 1\",\"required\":true,\"width\":100,\"height\":15}]"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/PagePaginationOptionsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net.Model.Requests; 4 | 5 | namespace UnitTests.Requests 6 | { 7 | [TestClass] 8 | public class PagePaginationOptionsTest 9 | { 10 | [TestMethod] 11 | public void CreateProperQueryString() 12 | { 13 | var noOptions = new PagePaginationOptions(); 14 | var pageOption = new PagePaginationOptions { Page = 1 }; 15 | var perPageOption = new PagePaginationOptions { PerPage = 10 }; 16 | var fullOption = new PagePaginationOptions { Page = 2, PerPage = 20 }; 17 | 18 | Assert.AreEqual(String.Empty, noOptions.ToQueryString()); 19 | Assert.AreEqual("page=1", pageOption.ToQueryString()); 20 | Assert.AreEqual("per_page=10", perPageOption.ToQueryString()); 21 | Assert.AreEqual("page=2&per_page=20", fullOption.ToQueryString()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/PrefillTextFieldRequestTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Internal.Requests; 3 | using SignNow.Net.Model.EditFields; 4 | using SignNow.Net.Test.FakeModels.EditFields; 5 | 6 | namespace UnitTests.Requests 7 | { 8 | [TestClass] 9 | public class PrefillTextFieldRequestTest 10 | { 11 | [TestMethod] 12 | public void ShouldProperCreateJsonRequest() 13 | { 14 | var textField = new TextField { Name = "Text_1", PrefilledText = "prefilled-text" }; 15 | 16 | var request1 = new PrefillTextFieldRequest(textField); 17 | var request2 = new PrefillTextFieldRequest(new TextFieldFaker().Generate(5)); 18 | 19 | var actual1 = $@"{{ 20 | ""fields"": [ 21 | {{ 22 | ""field_name"": ""Text_1"", 23 | ""prefilled_text"": ""prefilled-text"" 24 | }} 25 | ] 26 | }}"; 27 | 28 | Assert.That.JsonEqual(request1, actual1); 29 | Assert.AreEqual(5, request2.Fields.Count); 30 | Assert.IsTrue(request2.Fields.TrueForAll(itm => itm.FieldName.StartsWith("Text_"))); 31 | } 32 | 33 | [TestMethod] 34 | public void CreatesJsonContext() 35 | { 36 | var fields = new TextFieldFaker().Generate(5); 37 | var request = new PrefillTextFieldRequest(fields); 38 | 39 | var jsonHttpContext = request.GetHttpContent(); 40 | var jsonBody = jsonHttpContext.ReadAsStringAsync().Result; 41 | 42 | Assert.AreEqual("application/json", jsonHttpContext.Headers.ContentType?.MediaType); 43 | Assert.IsTrue(jsonBody.Contains("fields")); 44 | Assert.IsTrue(jsonBody.Contains("field_name")); 45 | Assert.IsTrue(jsonBody.Contains(fields[1].PrefilledText)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Requests/UpdateUserOptionsTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace UnitTests.Requests 4 | { 5 | [TestClass] 6 | public class UpdateUserOptionsTest : SignNowTestBase 7 | { 8 | [TestMethod] 9 | public void ShouldSerializeAllProperties() 10 | { 11 | var updateUserOptions = new SignNow.Net.Model.Requests.UpdateUserOptions 12 | { 13 | FirstName = "signNow", 14 | LastName = "SDK", 15 | OldPassword = "old-password", 16 | Password = "new-password", 17 | LogOutAll = false 18 | }; 19 | 20 | var expected = @"{ 21 | ""first_name"": ""signNow"", 22 | ""last_name"": ""SDK"", 23 | ""password"": ""new-password"", 24 | ""old_password"": ""old-password"", 25 | ""logout_all"": ""false"" 26 | }"; 27 | 28 | Assert.That.JsonEqual(updateUserOptions, expected); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Responses/EmbeddedInviteResponseTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using SignNow.Net.Model; 3 | 4 | namespace UnitTests.Responses 5 | { 6 | [TestClass] 7 | public class EmbeddedInviteResponseTest 8 | { 9 | [TestMethod] 10 | public void ShouldProperDeserialize() 11 | { 12 | var jsonResponse = @"{ 13 | 'data': [ 14 | { 15 | 'id': '03739a736d324f9794c2e93ec7c5bda817af3f7f', 16 | 'email': 'signer@email.com', 17 | 'role_id': '33d7925969c53b55dfc2ea6d5d1fc8e788d33821', 18 | 'order': 1, 19 | 'status': 'pending' 20 | }, 21 | { 22 | 'id': 'b926e550940746dda5206fa2bd8860ac7832b476', 23 | 'email': 'signer2@email.com', 24 | 'role_id': '8844a3615c875a74358cefa09424617e00909f0a', 25 | 'order': 1, 26 | 'status': 'pending' 27 | } 28 | ] 29 | }"; 30 | 31 | var response = TestUtils.DeserializeFromJson(jsonResponse); 32 | var inviteData1 = response.InviteData[0]; 33 | 34 | Assert.AreEqual(2, response.InviteData.Count); 35 | Assert.AreEqual("03739a736d324f9794c2e93ec7c5bda817af3f7f", inviteData1.Id); 36 | Assert.AreEqual("signer@email.com", inviteData1.Email); 37 | Assert.AreEqual("33d7925969c53b55dfc2ea6d5d1fc8e788d33821", inviteData1.RoleId); 38 | Assert.AreEqual(1, inviteData1.Order); 39 | Assert.AreEqual(InviteStatus.Pending, inviteData1.Status); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SignNow.Net.Test/UnitTests/Services/SignNowContextTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using SignNow.Net; 4 | using SignNow.Net.Model; 5 | using SignNow.Net.Service; 6 | 7 | namespace UnitTests.Services 8 | { 9 | [TestClass] 10 | public class SignNowContextTest 11 | { 12 | [TestMethod] 13 | public void ShouldCreateContextUsingToken() 14 | { 15 | var context = new SignNowContext(new Token()); 16 | 17 | Assert.IsInstanceOfType(context.OAuth, typeof(OAuth2Service)); 18 | Assert.IsInstanceOfType(context.Documents, typeof(DocumentService)); 19 | Assert.IsInstanceOfType(context.Invites, typeof(UserService)); 20 | Assert.IsInstanceOfType(context.Users, typeof(UserService)); 21 | Assert.IsInstanceOfType(context.Folders, typeof(FolderService)); 22 | Assert.IsInstanceOfType(context.DocumentGroup, typeof(DocumentGroupService)); 23 | } 24 | 25 | [TestMethod] 26 | public void CanSetAppCredentials() 27 | { 28 | var context = new SignNowContext(null); 29 | 30 | Assert.IsTrue(String.Empty.Equals(context.OAuth.ClientId)); 31 | Assert.IsTrue(String.Empty.Equals(context.OAuth.ClientSecret)); 32 | 33 | context.OAuth.ClientId = "CLIENT_ID"; 34 | context.OAuth.ClientSecret = "CLIENT_SECRET"; 35 | 36 | Assert.AreEqual("CLIENT_ID", context.OAuth.ClientId); 37 | Assert.AreEqual("CLIENT_SECRET", context.OAuth.ClientSecret); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/IContent.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | 3 | namespace SignNow.Net.Interfaces 4 | { 5 | /// 6 | /// Interface that represent for 7 | /// 8 | public interface IContent 9 | { 10 | HttpContent GetHttpContent(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/IFieldEditable.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using SignNow.Net.Model; 4 | 5 | namespace SignNow.Net.Interfaces 6 | { 7 | public interface IFieldEditable 8 | { 9 | /// 10 | /// The page number of the document. 11 | /// 12 | [JsonProperty("page_number")] 13 | int PageNumber { get; set; } 14 | 15 | /// 16 | /// The type of the Field. 17 | /// 18 | [JsonProperty("type")] 19 | [JsonConverter(typeof(StringEnumConverter))] 20 | FieldType Type { get; } 21 | 22 | /// 23 | /// The name of the Field. 24 | /// 25 | [JsonProperty("name")] 26 | string Name { get; set; } 27 | 28 | /// 29 | /// The name role of the field. 30 | /// 31 | [JsonProperty("role")] 32 | string Role { get; set; } 33 | 34 | /// 35 | /// Is field required or not. 36 | /// 37 | [JsonProperty("required")] 38 | bool Required { get; set; } 39 | 40 | /// 41 | /// X coordinate of the field. 42 | /// 43 | [JsonProperty("x")] 44 | public int X { get; set; } 45 | 46 | /// 47 | /// Y coordinate of the field. 48 | /// 49 | [JsonProperty("y")] 50 | public int Y { get; set; } 51 | 52 | /// 53 | /// Width of the field. 54 | /// 55 | [JsonProperty("width")] 56 | public int Width { get; set; } 57 | 58 | /// 59 | /// Height of the field. 60 | /// 61 | [JsonProperty("height")] 62 | public int Height { get; set; } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/IHttpContentAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Threading.Tasks; 3 | 4 | namespace SignNow.Net.Interfaces 5 | { 6 | public interface IHttpContentAdapter 7 | { 8 | /// 9 | /// Converts HTTP content to . 10 | /// 11 | /// Http response content 12 | Task Adapt(HttpContent content); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/IQueryToString.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Interfaces 2 | { 3 | /// 4 | /// Interface that allow to build http query string from DTO class properties 5 | /// 6 | public interface IQueryToString 7 | { 8 | /// 9 | /// Build http query string from class properties 10 | /// 11 | /// query string representation 12 | public string ToQueryString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ISignNowClient.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model; 2 | using System.IO; 3 | using System.Net.Http; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace SignNow.Net.Interfaces 8 | { 9 | public interface ISignNowClient 10 | { 11 | /// 12 | /// HTTP requests are being made here 13 | /// 14 | /// Type (Model) of the response from the request 15 | /// 16 | /// Propagates notification that operations should be canceled 17 | /// 18 | Task RequestAsync(RequestOptions requestOptions, CancellationToken cancellationToken = default); 19 | 20 | /// 21 | /// Type (Model) of the response from the request 22 | /// 23 | /// 24 | /// 25 | /// Propagates notification that operations should be canceled 26 | /// 27 | Task RequestAsync(RequestOptions requestOptions, IHttpContentAdapter adapter = default, HttpCompletionOption completionOption = default, CancellationToken cancellationToken = default); 28 | 29 | /// 30 | /// HTTP requests which returns Stream response 31 | /// 32 | /// 33 | /// Propagates notification that operations should be canceled 34 | /// response. 35 | Task RequestAsync(RequestOptions requestOptions, CancellationToken cancellationToken = default); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ISignNowContent.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.FieldContents; 2 | 3 | namespace SignNow.Net.Interfaces 4 | { 5 | /// 6 | /// Interface for all signNow content types retrieval. 7 | /// Resources that implement this interface can be used as signNow Content (Field Content). 8 | /// Possible concrete classes: 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | public interface ISignNowContent 19 | { 20 | /// 21 | /// Returns the value for any of SignNow content object. 22 | /// 23 | object GetValue(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ISignNowContext.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Interfaces 2 | { 3 | /// 4 | /// Interface that manages other signNow interfaces: IDocumentService, IUserService, ISignInvite, IFolderService. 5 | /// It contains: 6 | /// 7 | /// 8 | /// interface for any operations with a Document in signNow; 9 | /// can be used to create, download, retrieve, delete a document etc. 10 | /// 11 | /// 12 | /// interface for any operations with a User in signNow; 13 | /// i.e. create a user, authenticate a user, retrieve user's documents etc. 14 | /// 15 | /// 16 | /// interface for any operations with an Invite in signNow: 17 | /// creating or canceling the invite to sign a document, checking status of the invite, etc. 18 | /// 19 | /// 20 | /// interface for any operations with a Folders in signNow: 21 | /// can be used to create, view, rename or delete a folders. 22 | /// 23 | /// 24 | /// 25 | public interface ISignNowContext 26 | { 27 | /// 28 | IDocumentService Documents { get; } 29 | 30 | /// 31 | IUserService Users { get; } 32 | 33 | /// 34 | ISignInvite Invites { get; } 35 | 36 | /// 37 | IFolderService Folders { get; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ISignNowField.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model; 2 | using SignNow.Net.Model.FieldContents; 3 | 4 | namespace SignNow.Net.Interfaces 5 | { 6 | /// 7 | /// Interface for all signNow Fields. 8 | /// 9 | public interface ISignNowField 10 | { 11 | /// 12 | /// Get signNow field type. 13 | /// 14 | FieldType Type { get; } 15 | 16 | /// 17 | /// Returns identity for element with content. 18 | /// 19 | string ElementId { get; } 20 | 21 | /// 22 | /// Field attributes: name, label, x/y coordinates, width, height... 23 | /// 24 | FieldJsonAttributes JsonAttributes { get; } 25 | 26 | /// 27 | /// Field request ID 28 | /// 29 | string FieldRequestId { get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ISignNowInviteStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SignNow.Net.Model; 3 | 4 | namespace SignNow.Net.Interfaces 5 | { 6 | public interface ISignNowInviteStatus 7 | { 8 | /// 9 | /// Unique identifier of invite. 10 | /// 11 | string Id { get; } 12 | 13 | /// 14 | /// Signer email. 15 | /// 16 | string SignerEmail { get; } 17 | 18 | /// 19 | /// Status of the invite sign request. 20 | /// 21 | InviteStatus Status { get; } 22 | 23 | /// 24 | /// Timestamp invite was created. 25 | /// 26 | DateTime Created { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SignNow.Net/Interfaces/ITextTags.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Interfaces 2 | { 3 | public interface ITextTags 4 | { 5 | public string ToStringContent(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Company.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public class Company 6 | { 7 | /// 8 | /// Company name. 9 | /// 10 | [JsonProperty("name")] 11 | public string Name { get; set; } 12 | 13 | /// 14 | /// User have full access to Company when it belongs to Company domain. 15 | /// 16 | [JsonProperty("full_access")] 17 | public bool FullAccess { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/AttachmentTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public class AttachmentTag : ComplexTagWithLabel 7 | { 8 | /// 9 | [JsonProperty("type")] 10 | [JsonConverter(typeof(StringEnumConverter))] 11 | public override FieldType Type { get; protected set; } = FieldType.Attachment; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/CheckBoxTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public class CheckBoxTag : ComplexTagBase 7 | { 8 | /// 9 | [JsonProperty("type")] 10 | [JsonConverter(typeof(StringEnumConverter))] 11 | public override FieldType Type { get; protected set; } = FieldType.Checkbox; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/ComplexTagBase.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public abstract class ComplexTag 7 | { 8 | /// 9 | /// Field type 10 | /// 11 | [JsonProperty("type")] 12 | [JsonConverter(typeof(StringEnumConverter))] 13 | public virtual FieldType Type { get; protected set; } 14 | } 15 | 16 | public abstract class ComplexTagBase : ComplexTag 17 | { 18 | /// 19 | /// The name of the Tag 20 | /// 21 | [JsonProperty("tag_name")] 22 | public string TagName { get; set; } 23 | 24 | /// 25 | /// Which role the field is assigned to, e.g. Signer_1 26 | /// 27 | [JsonProperty("role")] 28 | public string Role { get; set; } 29 | 30 | /// 31 | /// Whether the field is mandatory to fill in 32 | /// 33 | [JsonProperty("required")] 34 | public bool Required { get; set; } 35 | 36 | /// 37 | /// How many pixels wide the field is 38 | /// 39 | [JsonProperty("width")] 40 | public int Width { get; set; } 41 | 42 | /// 43 | /// How many pixels high the field is 44 | /// 45 | [JsonProperty("height")] 46 | public int Height { get; set; } 47 | } 48 | 49 | public abstract class ComplexTagWithLabel : ComplexTagBase 50 | { 51 | /// 52 | /// (optional) - hint for the signer inside a fillable field about the field type, 53 | /// e.g. first_name or text_1; 54 | /// once the field is filled in, the value automatically appears in all the fields with the same label 55 | /// 56 | [JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)] 57 | public string Label { get; set; } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/DateValidatorTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | 5 | namespace SignNow.Net.Model.ComplexTags 6 | { 7 | public class DateValidatorTag : ComplexTagWithLabel 8 | { 9 | /// 10 | /// Field type 11 | /// 12 | [JsonProperty("type")] 13 | [JsonConverter(typeof(StringEnumConverter))] 14 | public override FieldType Type { get; protected set; } = FieldType.Text; 15 | 16 | /// 17 | /// Lock Signing Date option 18 | /// 19 | [JsonProperty("lock_to_sign_date", Order = 1)] 20 | public bool LockSigningDate { get; set; } 21 | 22 | /// 23 | /// Data validation format for a field 24 | /// 25 | [JsonProperty("validator_id", Order = 2)] 26 | [JsonConverter(typeof(StringEnumConverter))] 27 | public DataValidator Validator { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/DropdownTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SignNow.Net.Model.ComplexTags 6 | { 7 | public class DropdownTag : ComplexTagWithLabel 8 | { 9 | /// 10 | [JsonProperty("type")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public override FieldType Type { get; protected set; } = FieldType.Enumeration; 13 | 14 | [JsonProperty("custom_defined_option")] 15 | public bool CustomDefinedOptions { get; set; } 16 | 17 | [JsonProperty("enumeration_options")] 18 | public List EnumerationOptions { get; set; } = new List(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/HyperlinkTag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | using SignNow.Net.Internal.Helpers.Converters; 5 | 6 | namespace SignNow.Net.Model.ComplexTags 7 | 8 | { 9 | public class HyperlinkTag : ComplexTagWithLabel 10 | { 11 | /// 12 | [JsonProperty("type")] 13 | [JsonConverter(typeof(StringEnumConverter))] 14 | public override FieldType Type { get; protected set; } = FieldType.Hyperlink; 15 | 16 | /// 17 | /// Page number where is located hyperlink 18 | /// 19 | [JsonProperty("page_number")] 20 | public int PageNumber { get; set; } 21 | 22 | /// 23 | /// Hyperlink unique id 24 | /// 25 | [JsonProperty("name")] 26 | public string Name { get; set; } 27 | 28 | [JsonProperty("link")] 29 | [JsonConverter(typeof(StringToUriJsonConverter))] 30 | public Uri Link { get; set; } 31 | 32 | /// 33 | /// Hyperlink hint 34 | /// 35 | [JsonProperty("hint")] 36 | public string Hint { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/InitialsTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public class InitialsTag : ComplexTagBase 7 | { 8 | /// 9 | [JsonProperty("type")] 10 | [JsonConverter(typeof(StringEnumConverter))] 11 | public override FieldType Type { get; protected set; } = FieldType.Initials; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/SignatureTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public class SignatureTag : ComplexTagBase 7 | { 8 | /// 9 | [JsonProperty("type")] 10 | [JsonConverter(typeof(StringEnumConverter))] 11 | public override FieldType Type { get; protected set; } = FieldType.Signature; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTags/TextTag.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.ComplexTags 5 | { 6 | public class TextTag : ComplexTagWithLabel 7 | { 8 | /// 9 | [JsonProperty("type")] 10 | [JsonConverter(typeof(StringEnumConverter))] 11 | public override FieldType Type { get; protected set; } = FieldType.Text; 12 | 13 | /// 14 | /// Editable text (optional) that appears in the field when the signer opens the document, e.g. Lucy 15 | /// 16 | [JsonProperty("prefilled_text", NullValueHandling = NullValueHandling.Ignore)] 17 | public string PrefilledText { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SignNow.Net/Model/ComplexTextTags.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Interfaces; 4 | using SignNow.Net.Model.ComplexTags; 5 | 6 | namespace SignNow.Net.Model 7 | { 8 | public class ComplexTextTags : ITextTags 9 | { 10 | [JsonIgnore] 11 | public List Properties { get; set; } = new List(); 12 | 13 | public ComplexTextTags() { } 14 | 15 | public ComplexTextTags(ComplexTag tag) 16 | { 17 | Properties.Add(tag); 18 | } 19 | 20 | public string ToStringContent() 21 | { 22 | return JsonConvert.SerializeObject(Properties); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SignNow.Net/Model/DownloadType.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Model 2 | { 3 | /// 4 | /// Possible types for document downloads 5 | /// 6 | public enum DownloadType 7 | { 8 | /// 9 | /// Raw data of the PDF document that can be written to a blank `.pdf` file. 10 | /// This file - is original PDF uploaded by user. 11 | /// 12 | PdfOriginal, 13 | 14 | /// 15 | /// Raw data of the PDF document that can be written to a blank `.pdf` file. 16 | /// This file - is PDF document with filled fields. 17 | /// 18 | PdfCollapsed, 19 | 20 | /// 21 | /// Raw data of a ZIP file containing the PDF and any attachments 22 | /// on that document that can be written to blank a `.zip` file. 23 | /// 24 | ZipCollapsed, 25 | 26 | /// 27 | /// Raw data of the PDF collapsed document with a table containing the document's history. 28 | /// 29 | PdfWithHistory 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/Model/EditFields/AbstractField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SignNow.Net.Interfaces; 3 | 4 | namespace SignNow.Net.Model.EditFields 5 | { 6 | public abstract class AbstractField: IFieldEditable 7 | { 8 | private int pageNumber { get; set; } 9 | 10 | /// 11 | public int PageNumber 12 | { 13 | get { return pageNumber; } 14 | set 15 | { 16 | if (value < 0) { throw new ArgumentException("Value cannot be less than 0", nameof(PageNumber)); } 17 | 18 | pageNumber = value; 19 | } 20 | } 21 | 22 | /// 23 | public virtual FieldType Type { get; } 24 | 25 | /// 26 | public string Name { get; set; } 27 | 28 | /// 29 | public string Role { get; set; } 30 | 31 | /// 32 | public bool Required { get; set; } 33 | 34 | /// 35 | public int X { get; set; } 36 | 37 | /// 38 | public int Y { get; set; } 39 | 40 | /// 41 | public int Width { get; set; } 42 | 43 | /// 44 | public int Height { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SignNow.Net/Model/EditFields/TextField.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.EditFields 4 | { 5 | public class TextField: AbstractField 6 | { 7 | /// 8 | public override FieldType Type => FieldType.Text; 9 | 10 | /// 11 | /// Prefilled text value of the field. 12 | /// 13 | [JsonProperty("prefilled_text", NullValueHandling = NullValueHandling.Ignore)] 14 | public string PrefilledText { get; set; } 15 | 16 | /// 17 | /// Field label. 18 | /// 19 | [JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)] 20 | public string Label { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/AttachmentContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Interfaces; 3 | 4 | namespace SignNow.Net.Model.FieldContents 5 | { 6 | /// 7 | /// Represents signNow field types: `Attachment` 8 | /// 9 | public class AttachmentContent : BaseContent 10 | { 11 | /// 12 | /// Original attachment file name with extension. 13 | /// 14 | [JsonProperty("original_attachment_name")] 15 | public string OriginalName { get; set; } 16 | 17 | /// 18 | /// Filename with extension used in signNow. 19 | /// 20 | [JsonProperty("filename")] 21 | public string FileName { get; set; } 22 | 23 | /// 24 | /// File size in bytes. 25 | /// 26 | [JsonProperty("file_size")] 27 | public ulong FileSize { get; set; } 28 | 29 | /// 30 | public override object GetValue() => Id; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/BaseContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Interfaces; 3 | 4 | namespace SignNow.Net.Model.FieldContents 5 | { 6 | /// 7 | /// Basic signNow field content. 8 | /// 9 | public abstract class BaseContent : ISignNowContent 10 | { 11 | /// 12 | /// Identity of field. 13 | /// 14 | [JsonProperty("id")] 15 | public string Id {get; set; } 16 | 17 | /// 18 | /// Identity of User which fulfilled the field. 19 | /// 20 | [JsonProperty("user_id")] 21 | public string UserId { get; set; } 22 | 23 | /// 24 | /// The page number of the document. 25 | /// 26 | [JsonProperty("page_number")] 27 | public int PageNumber { get; set; } 28 | 29 | /// 30 | public abstract object GetValue(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/CheckboxContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.FieldContents 4 | { 5 | /// 6 | /// Represents signNow field types: `Checkbox` 7 | /// 8 | public class CheckboxContent : BaseContent 9 | { 10 | /// 11 | /// Email of user who fulfilled the field. 12 | /// 13 | [JsonProperty("email")] 14 | public string Email { get; set; } 15 | 16 | /// 17 | /// Checkbox value (checked or unchecked). 18 | /// 19 | [JsonIgnore] 20 | public bool Data { get; set; } 21 | 22 | /// 23 | /// Returns text value of field. 24 | /// 25 | public override string ToString() => Data ? "1" : ""; 26 | 27 | /// 28 | public override object GetValue() => Data; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/EnumerationContent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Interfaces; 4 | using SignNow.Net.Internal.Helpers.Converters; 5 | 6 | namespace SignNow.Net.Model.FieldContents 7 | { 8 | /// 9 | /// Represents an element of Enumeration options 10 | /// for `Dropdown` field type. 11 | /// 12 | public class EnumerationContent : ISignNowContent 13 | { 14 | /// 15 | /// Unique identifier of field. 16 | /// 17 | [JsonProperty("id")] 18 | public string Id { get; set; } 19 | 20 | /// 21 | /// Unique identifier of enumeration element. 22 | /// 23 | [JsonProperty("enumeration_id")] 24 | public string EnumerationId { get; set; } 25 | 26 | /// 27 | /// Enumeration value. 28 | /// 29 | [JsonProperty("data")] 30 | public string Data { get; set; } 31 | 32 | /// 33 | /// Timestamp enumeration was created. 34 | /// 35 | [JsonProperty("created")] 36 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 37 | public DateTime Created { get; set; } 38 | 39 | /// 40 | /// Timestamp enumeration was updated. 41 | /// 42 | [JsonProperty("updated")] 43 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 44 | public DateTime Updated { get; set; } 45 | 46 | /// 47 | public object GetValue() => Data; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/HyperlinkContent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | 5 | namespace SignNow.Net.Model.FieldContents 6 | { 7 | /// 8 | /// Represents signNow field types: `Hyperlink` 9 | /// 10 | public class HyperlinkContent : BaseContent 11 | { 12 | /// 13 | /// Email of user who fulfilled the field. 14 | /// 15 | [JsonProperty("email")] 16 | public string Email { get; set; } 17 | 18 | /// 19 | /// Hyperlink label. 20 | /// 21 | [JsonProperty("label")] 22 | public string Label {get; set; } 23 | 24 | /// 25 | /// Hyperlink field value 26 | /// 27 | [JsonProperty("data")] 28 | [JsonConverter(typeof(StringToUriJsonConverter))] 29 | public Uri Data { get; set; } 30 | 31 | /// 32 | /// Returns Hyperlink content as string. 33 | /// 34 | public override string ToString() => Data.OriginalString; 35 | 36 | /// 37 | public override object GetValue() => Data; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/SignatureContent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Internal.Helpers.Converters; 5 | 6 | namespace SignNow.Net.Model.FieldContents 7 | { 8 | /// 9 | /// Represents signNow field types: `Signature`, `Initials fields`. 10 | /// 11 | public class SignatureContent : BaseContent 12 | { 13 | /// 14 | /// Identity of the signature request. 15 | /// 16 | [JsonProperty("signature_request_id")] 17 | public string SignatureRequestId { get; set; } 18 | 19 | /// 20 | /// email who was signed the document. 21 | /// 22 | [JsonProperty("email")] 23 | public string Email { get; set; } 24 | 25 | /// 26 | /// Timestamp document was signed. 27 | /// 28 | [JsonProperty("created")] 29 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 30 | public DateTime Created { get; set; } 31 | 32 | /// 33 | /// Raw text value of the field. 34 | /// 35 | [JsonProperty("data")] 36 | [JsonConverter(typeof(StringBase64ToByteArrayJsonConverter))] 37 | [SuppressMessage("Properties should not return arrays", "CA1819")] 38 | public byte[] Data { get; set; } 39 | 40 | /// 41 | /// Returns SignatureContent content as base64 string. 42 | /// 43 | public override string ToString() 44 | { 45 | return Convert.ToBase64String(Data); 46 | } 47 | 48 | /// 49 | public override object GetValue() => Data; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SignNow.Net/Model/FieldContents/TextContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Interfaces; 3 | 4 | namespace SignNow.Net.Model.FieldContents 5 | { 6 | /// 7 | /// Represents signNow field types: `Text box`, `Dropdown box`, `Date-Time picker` 8 | /// 9 | public class TextContent : BaseContent 10 | { 11 | /// 12 | /// Email of user who fulfilled the field. 13 | /// 14 | [JsonProperty("email")] 15 | public string Email { get; set; } 16 | 17 | /// 18 | /// Raw text value of the field. 19 | /// 20 | [JsonProperty("data")] 21 | public string Data { get; set; } 22 | 23 | /// 24 | /// Returns text value of field. 25 | /// 26 | public override string ToString() => Data; 27 | 28 | /// 29 | public override object GetValue() => Data; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/Model/GrantType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public enum GrantType 6 | { 7 | [EnumMember(Value = "password")] 8 | Password, 9 | 10 | [EnumMember(Value = "refresh_token")] 11 | RefreshToken, 12 | 13 | [EnumMember(Value = "authorization_code")] 14 | AuthorizationCode 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Lang.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public enum Lang 6 | { 7 | [EnumMember(Value = "en")] 8 | English, 9 | 10 | [EnumMember(Value = "es")] 11 | Spanish, 12 | 13 | [EnumMember(Value = "fr")] 14 | French 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Organization.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public class Organization : IdResponse 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Owner.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public class Owner 6 | { 7 | [JsonProperty("id")] 8 | public string Id { get; set; } 9 | 10 | /// 11 | /// Email of document owner. 12 | /// 13 | [JsonProperty("email")] 14 | public string Email { get; set; } 15 | 16 | /// 17 | /// Organization info. 18 | /// 19 | [JsonProperty("organization", NullValueHandling = NullValueHandling.Ignore)] 20 | public Organization Organization { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Pagination.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | 5 | namespace SignNow.Net.Model 6 | { 7 | public class Pagination 8 | { 9 | [JsonProperty("total")] 10 | public int Total { get; set; } 11 | 12 | [JsonProperty("count")] 13 | public int Count { get; set; } 14 | 15 | [JsonProperty("per_page")] 16 | public int PerPage { get; set; } 17 | 18 | [JsonProperty("current_page")] 19 | public int CurrentPage { get; set; } 20 | 21 | [JsonProperty("total_pages")] 22 | public int TotalPages { get; set; } 23 | 24 | [JsonProperty("links", NullValueHandling = NullValueHandling.Ignore)] 25 | public PageLinks Links { get; set; } 26 | } 27 | 28 | public class PageLinks 29 | { 30 | [JsonProperty("previous", NullValueHandling = NullValueHandling.Ignore)] 31 | [JsonConverter(typeof(StringToUriJsonConverter))] 32 | public Uri Previous { get; set; } 33 | 34 | [JsonProperty("next", NullValueHandling = NullValueHandling.Ignore)] 35 | [JsonConverter(typeof(StringToUriJsonConverter))] 36 | public Uri Next { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SignNow.Net/Model/RedirectTarget.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | public enum RedirectTarget 6 | { 7 | /// 8 | /// opens the link in the new tab 9 | /// 10 | [EnumMember(Value = "blank")] 11 | Blank, 12 | 13 | /// 14 | /// opens the link in the same tab. 15 | /// 16 | [EnumMember(Value = "self")] 17 | Self 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SignNow.Net/Model/RequestOptions.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Service; 2 | using System; 3 | using System.Net.Http; 4 | using SignNow.Net.Interfaces; 5 | using Method = System.Net.Http.HttpMethod; 6 | 7 | namespace SignNow.Net.Model 8 | { 9 | public abstract class RequestOptions 10 | { 11 | public IContent Content { get; set; } 12 | 13 | public Uri RequestUrl { get; set; } 14 | 15 | public abstract Method HttpMethod { get; } 16 | 17 | public Token Token { get; set; } 18 | 19 | } 20 | 21 | public class GetHttpRequestOptions : RequestOptions 22 | { 23 | public override Method HttpMethod => Method.Get; 24 | } 25 | 26 | public class PostHttpRequestOptions : RequestOptions 27 | { 28 | public override Method HttpMethod => Method.Post; 29 | 30 | public PostHttpRequestOptions(IContent ContentObj = null) 31 | { 32 | Content = ContentObj; 33 | } 34 | } 35 | 36 | public class PutHttpRequestOptions : RequestOptions 37 | { 38 | public override Method HttpMethod => Method.Put; 39 | 40 | public PutHttpRequestOptions(IContent ContentObj = null) 41 | { 42 | Content = ContentObj; 43 | } 44 | } 45 | 46 | public class DeleteHttpRequestOptions : RequestOptions 47 | { 48 | public override Method HttpMethod => Method.Delete; 49 | } 50 | 51 | public class HeadHttpRequestOptions : RequestOptions 52 | { 53 | public override Method HttpMethod => Method.Head; 54 | } 55 | 56 | public class OptionsHttpRequestOptions : RequestOptions 57 | { 58 | public override Method HttpMethod => Method.Options; 59 | } 60 | } -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/CreateEmbedLinkOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SignNow.Net.Model.Requests 6 | { 7 | public class CreateEmbedLinkOptions 8 | { 9 | private uint? linkExpiration { get; set; } 10 | 11 | /// 12 | /// Signer authentication method. 13 | /// 14 | [JsonProperty("auth_method")] 15 | [JsonConverter(typeof(StringEnumConverter))] 16 | public EmbeddedAuthType AuthMethod { get; set; } = EmbeddedAuthType.None; 17 | 18 | /// 19 | /// In how many minutes the link expires, ranges from 15 to 45 minutes or null. 20 | /// 21 | [JsonProperty("link_expiration")] 22 | public uint? LinkExpiration { get; set; } 23 | 24 | /// 25 | /// Signature invite you'd like to embed. 26 | /// 27 | [JsonIgnore] 28 | public FieldInvite FieldInvite { get; set; } 29 | } 30 | 31 | public enum EmbeddedAuthType 32 | { 33 | [EnumMember(Value = "password")] 34 | Password, 35 | 36 | [EnumMember(Value = "email")] 37 | Email, 38 | 39 | [EnumMember(Value = "mfa")] 40 | Mfa, 41 | 42 | [EnumMember(Value = "social")] 43 | Social, 44 | 45 | [EnumMember(Value = "biometric")] 46 | Biometric, 47 | 48 | [EnumMember(Value = "other")] 49 | Other, 50 | 51 | [EnumMember(Value = "none")] 52 | None 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/CreateEventSubscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SignNow.Net.Internal.Extensions; 3 | using SignNow.Net.Internal.Helpers; 4 | using SignNow.Net.Model.Requests.EventSubscriptionBase; 5 | 6 | namespace SignNow.Net.Model.Requests 7 | { 8 | public sealed class CreateEventSubscription : AbstractEventSubscription 9 | { 10 | public CreateEventSubscription(EventType eventType, string entityId, Uri callbackUrl) 11 | { 12 | Guard.ArgumentNotNull(callbackUrl, nameof(callbackUrl)); 13 | 14 | Event = eventType; 15 | EntityId = entityId.ValidateId(); 16 | Attributes.CallbackUrl = callbackUrl; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/CreateUserOptions.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Requests 4 | { 5 | public class CreateUserOptions : JsonHttpContent 6 | { 7 | /// 8 | /// User email. 9 | /// 10 | [JsonProperty("email")] 11 | public string Email { get; set; } 12 | 13 | /// 14 | /// User password. 15 | /// 16 | [JsonProperty("password")] 17 | public string Password { get; set; } 18 | 19 | /// 20 | /// User firstname. 21 | /// 22 | [JsonProperty("first_name")] 23 | public string FirstName { get; set; } 24 | 25 | /// 26 | /// User lastname. 27 | /// 28 | [JsonProperty("last_name")] 29 | public string LastName { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/DocumentGroup/CopyDocumentGroupRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | 5 | namespace SignNow.Net.Model.Requests.DocumentGroup 6 | { 7 | public class CopyDocumentGroupRequest : JsonHttpContent 8 | { 9 | /// 10 | /// The name of the new document group copy. 11 | /// 12 | [JsonProperty("document_group_name")] 13 | public string DocumentGroupName { get; set; } 14 | 15 | /// 16 | /// Timestamp document was created. 17 | /// 18 | [JsonProperty("client_timestamp")] 19 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 20 | public DateTime ClientTimestamp { get; set; } = DateTime.UtcNow; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/DocumentGroup/DocumentHistoryType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace SignNow.Net.Model.Requests.DocumentGroup 4 | { 5 | /// 6 | /// Whether or not to attach document history to the download. 7 | /// 8 | public enum DocumentHistoryType 9 | { 10 | /// 11 | /// Do not attach document history to the download. 12 | /// 13 | [EnumMember(Value = "no")] 14 | NoHistory, 15 | 16 | /// 17 | /// Attach document history to the download after each document. 18 | /// 19 | [EnumMember(Value = "after_each_document")] 20 | AfterEachDocument, 21 | 22 | /// 23 | /// Attach document history to the download after the merged PDF. 24 | /// 25 | [EnumMember(Value = "after_merged_pdf")] 26 | AfterMergedPdf 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/DocumentGroup/DownloadOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SignNow.Net.Model.Requests.DocumentGroup 6 | { 7 | public class DownloadOptions : JsonHttpContent 8 | { 9 | /// 10 | [JsonProperty("type")] 11 | [JsonConverter(typeof(StringEnumConverter))] 12 | public DownloadType DownloadType { get; set; } = DownloadType.Zip; 13 | 14 | /// 15 | [JsonProperty("with_history")] 16 | [JsonConverter(typeof(StringEnumConverter))] 17 | public DocumentHistoryType WithHistory { get; set; } = DocumentHistoryType.NoHistory; 18 | 19 | /// 20 | /// The order of documents in the merged file. e.g: ordered list with signNow document ids. 21 | /// 22 | [JsonProperty("document_order", NullValueHandling = NullValueHandling.Ignore)] 23 | public List DocumentOrder { get; set; } = new List(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/DocumentGroup/DownloadType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace SignNow.Net.Model.Requests.DocumentGroup 4 | { 5 | /// 6 | /// Types of download for document group 7 | /// 8 | public enum DownloadType 9 | { 10 | /// 11 | /// zipped binary file (application/zip content) 12 | /// 13 | [EnumMember(Value = "zip")] 14 | Zip, 15 | 16 | /// 17 | /// pdf file that contains all the documents of the group 18 | /// 19 | [EnumMember(Value = "merged")] 20 | MergedPdf, 21 | 22 | /// 23 | /// pdf file with all the documents + attachments, all with the document group stamp, with history. 24 | /// 25 | [EnumMember(Value = "certificate")] 26 | PdfWithCertificate, 27 | 28 | /// 29 | /// returns zip file with document group that has ID on each page at the documents, attachments and history file in case history has been requested. 30 | /// 31 | [EnumMember(Value = "email")] 32 | ZipForEmail 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/EventSubscriptionBase/AbstractEventSubscription.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model.Requests.EventSubscriptionBase 5 | { 6 | public abstract class AbstractEventSubscription : JsonHttpContent 7 | { 8 | /// 9 | /// Event type. 10 | /// 11 | [JsonProperty("event")] 12 | [JsonConverter(typeof(StringEnumConverter))] 13 | public EventType Event { get; set; } 14 | 15 | /// 16 | /// The unique ID of the event: "document_id", "user_id", "document_group_id", "template_id". 17 | /// 18 | [JsonProperty("entity_id", NullValueHandling = NullValueHandling.Ignore)] 19 | public string EntityId { get; protected set; } 20 | 21 | /// 22 | /// Always only "callback" 23 | /// 24 | [JsonProperty("action")] 25 | public string Action = "callback"; 26 | 27 | /// 28 | /// Event attributes. 29 | /// 30 | [JsonProperty("attributes")] 31 | public EventCreateAttributes Attributes { get; set; } = new EventCreateAttributes(); 32 | 33 | /// 34 | /// Enables the HMAC security logic. 35 | /// 36 | [JsonProperty("secret_key", NullValueHandling = NullValueHandling.Ignore)] 37 | public string SecretKey { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/GetFolderQuery/FolderOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SignNow.Net.Model.Requests.GetFolderQuery 6 | { 7 | [JsonConverter(typeof(StringEnumConverter))] 8 | public enum SubFolders 9 | { 10 | [EnumMember(Value = "0")] 11 | DoNotShow, 12 | 13 | [EnumMember(Value = "1")] 14 | Show 15 | } 16 | 17 | [JsonConverter(typeof(StringEnumConverter))] 18 | public enum EntityType 19 | { 20 | [EnumMember(Value = "all")] 21 | All, 22 | 23 | [EnumMember(Value = "document")] 24 | Document, 25 | 26 | [EnumMember(Value = "document-group")] 27 | DocumentGroup, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/JsonHttpContent.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Text; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Interfaces; 5 | 6 | namespace SignNow.Net.Model.Requests 7 | { 8 | public abstract class JsonHttpContent : IContent 9 | { 10 | /// 11 | /// Creates Json Http Content from object 12 | /// 13 | /// HttpContent 14 | public HttpContent GetHttpContent() 15 | { 16 | return new StringContent( 17 | JsonConvert.SerializeObject(this), 18 | Encoding.UTF8, "application/json"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/LimitOffsetOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using SignNow.Net.Interfaces; 4 | 5 | namespace SignNow.Net.Model.Requests 6 | { 7 | public class LimitOffsetOptions : IQueryToString 8 | { 9 | /// 10 | /// Limit of the items in response. 11 | /// 12 | public int? Limit { get; set; } 13 | 14 | /// 15 | /// Offset size for pagination. 16 | /// 17 | public int? Offset { get; set; } 18 | 19 | public string ToQueryString() 20 | { 21 | if (Limit == null && Offset == null) 22 | { 23 | return String.Empty; 24 | } 25 | 26 | var options = new List(); 27 | 28 | if (Limit != null) 29 | { 30 | options.Add($"limit={Limit}"); 31 | } 32 | 33 | if (Offset != null) 34 | { 35 | options.Add($"offset={Offset}"); 36 | } 37 | 38 | return String.Join("&", options); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/MultipartHttpContent.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net.Http; 3 | using SignNow.Net.Interfaces; 4 | using System.Text; 5 | 6 | namespace SignNow.Net.Model.Requests 7 | { 8 | /// 9 | /// A container for content encoded using multipart/form-data MIME type. 10 | /// 11 | public class MultipartHttpContent : IContent 12 | { 13 | private readonly Stream _streamContent; 14 | private readonly string _fileName; 15 | private readonly ITextTags _textTags; 16 | 17 | public MultipartHttpContent(Stream content, string fileName, ITextTags tags) 18 | { 19 | _streamContent = content; 20 | _fileName = fileName; 21 | _textTags = tags; 22 | } 23 | 24 | // [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose HttpContent object before losing scope", Justification = "It should be disposed via HttpContent.Dispose()")] 25 | public HttpContent GetHttpContent() 26 | { 27 | var content = new MultipartFormDataContent(); 28 | content.Add(new StreamContent(_streamContent), "file", _fileName); 29 | 30 | if (_textTags != null) 31 | { 32 | content.Add(new StringContent(_textTags.ToStringContent(), Encoding.UTF8), "Tags"); 33 | } 34 | 35 | return content; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/PagePaginationOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using SignNow.Net.Interfaces; 4 | 5 | namespace SignNow.Net.Model.Requests 6 | { 7 | public class PagePaginationOptions : IQueryToString 8 | { 9 | public int? Page { get; set; } 10 | public int? PerPage { get; set; } 11 | 12 | public string ToQueryString() 13 | { 14 | if (Page == null && PerPage == null) 15 | { 16 | return String.Empty; 17 | } 18 | 19 | var options = new List(); 20 | if (Page != null) 21 | { 22 | options.Add($"page={Page}"); 23 | } 24 | if (PerPage != null) 25 | { 26 | options.Add($"per_page={PerPage}"); 27 | } 28 | 29 | return String.Join("&", options); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/UpdateEventSubscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Extensions; 4 | using SignNow.Net.Model.Requests.EventSubscriptionBase; 5 | 6 | namespace SignNow.Net.Model.Requests 7 | { 8 | public sealed class UpdateEventSubscription : AbstractEventSubscription 9 | { 10 | /// 11 | /// Identity of Event 12 | /// 13 | [JsonIgnore] 14 | public string Id { get; private set; } 15 | 16 | public UpdateEventSubscription(EventType eventType, string entityId, string eventId, Uri callbackUrl) 17 | { 18 | Id = eventId.ValidateId(); 19 | EntityId = entityId.ValidateId(); 20 | Event = eventType; 21 | Attributes.CallbackUrl = callbackUrl; 22 | } 23 | 24 | public UpdateEventSubscription(EventSubscription update) 25 | { 26 | Id = update.Id; 27 | EntityId = update.EntityUid; 28 | Attributes = new EventCreateAttributes 29 | { 30 | CallbackUrl = update.JsonAttributes.CallbackUrl, 31 | DocIdQueryParam = update.JsonAttributes.DocIdQueryParam, 32 | Headers = update.JsonAttributes.Headers, 33 | UseTls12 = update.JsonAttributes.UseTls12, 34 | IntegrationId = update.JsonAttributes.IntegrationId, 35 | }; 36 | SecretKey = update.JsonAttributes.SecretKey; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Requests/UpdateUserOptions.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Internal.Helpers.Converters; 3 | 4 | namespace SignNow.Net.Model.Requests 5 | { 6 | public class UpdateUserOptions : JsonHttpContent 7 | { 8 | /// 9 | /// User firstname. 10 | /// 11 | [JsonProperty("first_name")] 12 | public string FirstName { get; set; } 13 | 14 | /// 15 | /// User lastname. 16 | /// 17 | [JsonProperty("last_name")] 18 | public string LastName { get; set; } 19 | 20 | /// 21 | /// User password. 22 | /// 23 | [JsonProperty("password")] 24 | public string Password { get; set; } 25 | 26 | /// 27 | /// Old User password. 28 | /// 29 | [JsonProperty("old_password")] 30 | public string OldPassword { get; set; } 31 | 32 | /// 33 | /// if "true" - all user tokens with Scope expire 34 | /// if "false" - all user tokens except current one are expired 35 | /// 36 | [JsonProperty("logout_all")] 37 | [JsonConverter(typeof(BoolToStringJsonConverter))] 38 | public bool LogOutAll { get; set; } = true; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/CreateDocumentFromTemplateResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | /// 6 | /// Represents response from signNow API for Create Document from Template request. 7 | /// 8 | public class CreateDocumentFromTemplateResponse :IdResponse 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/CreateTemplateFromDocumentResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Responses.GenericResponses; 3 | 4 | namespace SignNow.Net.Model.Responses 5 | { 6 | /// 7 | /// Represents response from signNow API for Create Template from Document request. 8 | /// 9 | [JsonObject] 10 | public class CreateTemplateFromDocumentResponse : IdResponse { } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/DocumentGroupCreateResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | /// 6 | /// Represents response from signNow API for Create Document Group request. 7 | /// 8 | public class DocumentGroupCreateResponse : IdResponse { } 9 | } 10 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/DownloadDocumentResponse.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | /// 6 | /// Represents response from signNow API for Document download request. 7 | /// 8 | public class DownloadDocumentResponse 9 | { 10 | /// 11 | /// File name with extension. 12 | /// 13 | public string Filename { get; set; } 14 | 15 | /// 16 | /// File length in bytes. 17 | /// 18 | public long Length { get; set; } 19 | 20 | /// 21 | /// Type of content. 22 | /// 23 | public string MediaType { get; set; } 24 | 25 | /// 26 | /// File contents as Stream. 27 | /// 28 | public Stream Document { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/DownloadLinkResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represents response for creating one-time link to download document with embedded fields and elements. 8 | /// Link can be used once and then will expire. 9 | /// 10 | public class DownloadLinkResponse 11 | { 12 | /// 13 | /// Link to download specified document in PDF format. 14 | /// 15 | [JsonProperty("link")] 16 | public Uri Url { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EditDocumentResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | /// 6 | /// Represents response for edit document. 7 | /// 8 | public class EditDocumentResponse : IdResponse 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EmbeddedInviteLinkResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace SignNow.Net.Model 6 | { 7 | public class EmbeddedInviteLinkResponse 8 | { 9 | [JsonProperty("data")] 10 | internal Dictionary Data { get; set; } 11 | 12 | /// 13 | /// Returns the embedded invite link data for newly created embedded invite. 14 | /// 15 | [JsonIgnore] 16 | public Uri Link => Data["link"]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EmbeddedInviteResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | using SignNow.Net.Model.Responses.GenericResponses; 5 | 6 | namespace SignNow.Net.Model 7 | { 8 | /// 9 | /// Represents response from signNow API for create embedded invite request. 10 | /// 11 | public class EmbeddedInviteData : IdResponse 12 | { 13 | /// 14 | /// Signer's email address. 15 | /// 16 | [JsonProperty("email")] 17 | public string Email { get; set; } 18 | 19 | /// 20 | /// Signer's role ID. 21 | /// 22 | [JsonProperty("role_id")] 23 | public string RoleId { get; set; } 24 | 25 | /// 26 | /// Order of signing. Cannot be 0. 27 | /// 28 | [JsonProperty("order")] 29 | public int Order { get; set; } 30 | 31 | /// 32 | /// Current signing status. 33 | /// 34 | [JsonProperty("status")] 35 | [JsonConverter(typeof(StringEnumConverter))] 36 | public InviteStatus Status { get; set; } 37 | } 38 | 39 | public class EmbeddedInviteResponse 40 | { 41 | /// 42 | /// Returns the invite data for newly created embedded invite. 43 | /// 44 | [JsonProperty("data")] 45 | public IReadOnlyList InviteData { get; internal set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EventHistoryListResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | public class EventHistoryListResponse 6 | { 7 | [JsonProperty("meta")] 8 | public MetaInfo Meta { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EventSubscriptionInfoResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | public class EventSubscriptionInfoResponse 6 | { 7 | [JsonProperty("data")] 8 | public EventSubscription ResponseData { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EventSubscriptionResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Model.Responses 5 | { 6 | public class EventSubscriptionResponse 7 | { 8 | [JsonProperty("data")] 9 | public List Data { get; internal set; } 10 | 11 | [JsonProperty("meta")] 12 | public MetaInfo Meta { get; internal set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/EventUpdateResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | public class EventUpdateResponse : IdResponse 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/FolderIdentityResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | public class FolderIdentityResponse : IdResponse 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/GenericResponses/IdResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Responses.GenericResponses 4 | { 5 | /// 6 | /// Represents response from signNow API with identity of the signNow object. 7 | /// 8 | public abstract class IdResponse 9 | { 10 | [JsonProperty("id")] 11 | public string Id { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/InviteResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Responses.GenericResponses; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represents response from signNow API for create invite request. 8 | /// 9 | public class InviteResponse : IdResponse 10 | { 11 | /// 12 | /// Role-based invite status 13 | /// 14 | [JsonProperty("status")] 15 | public string Status { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/MetaInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | public class MetaInfo 6 | { 7 | [JsonProperty("pagination")] 8 | public Pagination Pagination { get; internal set; } 9 | } 10 | } -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/SigningLinkResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represents response from signNow API for signing link creation request. 8 | /// 9 | public class SigningLinkResponse 10 | { 11 | /// 12 | /// URL to sign the document via web browser using signNow credentials. 13 | /// 14 | [JsonProperty("url")] 15 | public Uri Url { get; set; } 16 | 17 | /// 18 | /// URL to sign the document via web browser without signNow credentials. 19 | /// 20 | [JsonProperty("url_no_signup")] 21 | public Uri AnonymousUrl { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/SuccessStatusResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SignNow.Net.Model.Responses 4 | { 5 | /// 6 | /// Represents successful status response from signNow API. 7 | /// 8 | public class SuccessStatusResponse 9 | { 10 | /// 11 | /// Operation status 12 | /// 13 | [JsonProperty("status")] 14 | public string Status { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/UploadDocumentResponse.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model.Responses.GenericResponses; 2 | 3 | namespace SignNow.Net.Model 4 | { 5 | /// 6 | /// Represents response from signNow API for upload document request. 7 | /// 8 | public class UploadDocumentResponse : IdResponse 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/UserCreateResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Responses.GenericResponses; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represents response from signNow API for User create request. 8 | /// 9 | public class UserCreateResponse : IdResponse 10 | { 11 | /// 12 | /// User is verified or not. 13 | /// 14 | [JsonProperty("verified")] 15 | public bool Verified { get; set; } 16 | 17 | /// 18 | /// User email. 19 | /// 20 | [JsonProperty("email")] 21 | public string Email { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Responses/UserUpdateResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Responses.GenericResponses; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represents response from signNow API for User update request. 8 | /// 9 | public class UserUpdateResponse : IdResponse 10 | { 11 | /// 12 | /// User firstname. 13 | /// 14 | [JsonProperty("first_name")] 15 | public string FirstName { get; set; } 16 | 17 | /// 18 | /// User lastname. 19 | /// 20 | [JsonProperty("last_name")] 21 | public string LastName { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Role.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Internal.Helpers.Converters; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// Represent document signer roles. 8 | /// 9 | public class Role 10 | { 11 | /// 12 | /// Role unique id. 13 | /// 14 | [JsonProperty("unique_id")] 15 | public string Id { get; set; } 16 | 17 | /// 18 | /// Role signing order. 19 | /// 20 | [JsonProperty("signing_order")] 21 | [JsonConverter(typeof(StringToIntJsonConverter))] 22 | public int SigningOrder { get; set; } 23 | 24 | /// 25 | /// Role signing name. 26 | /// 27 | [JsonProperty("name")] 28 | public string Name { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Scope.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.Serialization; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// The scope granted to the access token. 8 | /// 9 | public enum Scope 10 | { 11 | /// 12 | /// Scope which granted access to all services. 13 | /// 14 | [EnumMember(Value = "*")] 15 | All, 16 | 17 | /// 18 | /// Scope which granted access to User service. 19 | /// 20 | [EnumMember(Value = "user")] 21 | User 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net/Model/SignStatus.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Model 2 | { 3 | /// 4 | /// Represents statuses of document signing state. 5 | /// 6 | public enum DocumentStatus 7 | { 8 | /// 9 | /// Status for case when the document haven't any sign request. 10 | /// 11 | NoInvite, 12 | 13 | /// 14 | /// Status for case when the document have one or many sign requests which are not signed yet. 15 | /// 16 | Pending, 17 | 18 | /// 19 | /// Status for case when the document have one or many sign requests which are all signed. 20 | /// 21 | Completed 22 | } 23 | 24 | /// 25 | /// Represents statuses for fields (field invite or role-based invite) 26 | /// 27 | public enum InviteStatus 28 | { 29 | /// 30 | /// Status of field for document group when invite or action has been created but is not waiting to be signed. 31 | /// 32 | Created, 33 | 34 | /// 35 | /// Status of field for case when the document have one or many sign requests which are not signed yet. 36 | /// 37 | Pending, 38 | 39 | /// 40 | /// Status of field for case when the fill form in the document was filled by signer. 41 | /// 42 | Fulfilled, 43 | 44 | /// 45 | /// Status of field for document with conditional fields which can be skipped 46 | /// by choosing one of condition. 47 | /// 48 | Skipped 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Thumbnail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Internal.Helpers.Converters; 4 | 5 | namespace SignNow.Net.Model 6 | { 7 | /// 8 | /// Represents thumbnails of the document. 9 | /// 10 | public class Thumbnail 11 | { 12 | /// 13 | /// Uri for small document preview image size. 14 | /// A4 (210 x 297 mm) ~ 85 x 110 px @ 10 ppi 15 | /// 16 | [JsonProperty("small")] 17 | [JsonConverter(typeof(StringToUriJsonConverter))] 18 | public Uri Small { get; internal set; } 19 | 20 | /// 21 | /// Uri for medium document preview image size 22 | /// A4 (210 x 297 mm) ~ 340 x 440 px @ 40 ppi 23 | /// 24 | [JsonProperty("medium")] 25 | [JsonConverter(typeof(StringToUriJsonConverter))] 26 | public Uri Medium { get; internal set; } 27 | 28 | /// 29 | /// Uri for large document preview image size. 30 | /// A4 (210 x 297 mm) ~ 890 x 1151 px @ 104 ppi 31 | /// 32 | [JsonProperty("large")] 33 | [JsonConverter(typeof(StringToUriJsonConverter))] 34 | public Uri Large { get; internal set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SignNow.Net/Model/Token.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SignNow.Net.Model 5 | { 6 | /// 7 | /// The access token you can use to make requests on behalf of this signNow account. 8 | /// 9 | public class Token 10 | { 11 | /// 12 | /// Time in seconds for which the was issued. 13 | /// 14 | [JsonProperty("expires_in")] 15 | public int ExpiresIn { get; set; } 16 | 17 | /// 18 | /// Access 19 | /// 20 | [JsonProperty("access_token")] 21 | public string AccessToken { get; set; } 22 | 23 | /// 24 | /// Refresh 25 | /// 26 | [JsonProperty("refresh_token")] 27 | public string RefreshToken { get; set; } 28 | 29 | /// 30 | /// Access 31 | /// 32 | [JsonProperty("scope")] 33 | public string Scope { get; set; } 34 | 35 | /// 36 | /// Type of access token (e.g. 'bearer') 37 | /// 38 | [JsonProperty("token_type")] 39 | [JsonConverter(typeof(StringEnumConverter))] 40 | public TokenType TokenType { get; set; } 41 | 42 | [JsonProperty("last_login")] 43 | public int LastLogin { get; set; } 44 | 45 | /// 46 | /// Application Basic Token. 47 | /// 48 | [JsonIgnore] 49 | public string AppToken { get; set; } 50 | 51 | /// 52 | /// Returns formatted Authorization header param 53 | /// 54 | /// String value in format: 'bearer access_token' 55 | public string GetAuthorizationHeaderValue() 56 | { 57 | return TokenType == TokenType.Basic 58 | ? $"{TokenType.Basic} {AppToken}" 59 | : $"{TokenType} {AccessToken}"; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SignNow.Net/Model/TokenType.cs: -------------------------------------------------------------------------------- 1 | namespace SignNow.Net.Model 2 | { 3 | /// 4 | /// Represents types of Token. 5 | /// 6 | public enum TokenType 7 | { 8 | Basic, 9 | Bearer 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/Model/UserBilling.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Internal.Helpers.Converters; 5 | 6 | namespace SignNow.Net.Model 7 | { 8 | /// 9 | /// User billing period data 10 | /// 11 | public class UserBilling 12 | { 13 | [JsonProperty("start_date")] 14 | internal string Start => StartDate.Date.ToString("d", DateTimeFormatInfo.InvariantInfo); 15 | 16 | [JsonProperty("end_date")] 17 | internal string End => EndDate.Date.ToString("d", DateTimeFormatInfo.InvariantInfo); 18 | 19 | /// 20 | /// User billing period start date. 21 | /// 22 | [JsonProperty("start_timestamp")] 23 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 24 | public DateTime StartDate { get; set; } 25 | 26 | /// 27 | /// User billing period end date. 28 | /// 29 | [JsonProperty("end_timestamp")] 30 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 31 | public DateTime EndDate { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SignNow.Net/Properties/AsseblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | #if DEBUG 4 | [assembly: InternalsVisibleTo("SignNow.Net.Test")] 5 | [assembly: InternalsVisibleTo("Bogus")] 6 | // Requires for Moq ProxyBuilder 7 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 8 | #endif 9 | -------------------------------------------------------------------------------- /SignNow.Net/Service/WebClientBase.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Interfaces; 2 | using System; 3 | using SignNow.Net.Model; 4 | 5 | namespace SignNow.Net.Service 6 | { 7 | public abstract class WebClientBase 8 | { 9 | /// 10 | /// signNow HTTP Client. 11 | /// 12 | protected ISignNowClient SignNowClient { get; private set; } 13 | 14 | /// 15 | /// User Access token. 16 | /// 17 | public Token Token { get; set; } 18 | 19 | /// 20 | /// Base signNow api URL. 21 | /// 22 | protected Uri ApiBaseUrl { get; set; } 23 | 24 | /// 25 | /// Base Web Client for HTTP calls 26 | /// 27 | /// Base signNow api URL 28 | /// User Access token 29 | /// signNow HTTP Client 30 | protected WebClientBase(Uri apiBaseUrl, Token token, ISignNowClient signNowClient) 31 | { 32 | ApiBaseUrl = apiBaseUrl; 33 | Token = token; 34 | SignNowClient = signNowClient ?? new SignNowClient(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Constants/ApiUrl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SignNow.Net.Internal.Constants 4 | { 5 | /// 6 | /// Determines base signNow API URL. 7 | /// 8 | internal static class ApiUrl 9 | { 10 | #if DEBUG 11 | /// 12 | /// Base signNow API URL for Debug configuration. 13 | /// 14 | public static Uri ApiBaseUrl = new Uri("https://api-eval.signnow.com"); 15 | #else 16 | /// 17 | /// Base signNow API URL for Release configuration. 18 | /// 19 | public static Uri ApiBaseUrl = new Uri("https://api.signnow.com"); 20 | #endif 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Extensions/ScopeExtensions.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Model; 2 | using System; 3 | 4 | namespace SignNow.Net.Internal.Extensions 5 | { 6 | static class ScopeExtensions 7 | { 8 | public static string AsString(this Scope scope) 9 | { 10 | switch (scope) 11 | { 12 | case Scope.All: return "*"; 13 | case Scope.User: return "user"; 14 | default: throw new NotImplementedException($"Unable to convert scope value {scope} to string."); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/BoolToIntJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Internal.Helpers.Converters 5 | { 6 | /// 7 | /// Converts to 8 | /// 9 | internal class BoolToIntJsonConverter : JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 12 | { 13 | writer.WriteValue(((bool)value) ? 1 : 0); 14 | } 15 | 16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 17 | { 18 | return reader.Value.ToString() == "1"; 19 | } 20 | 21 | public override bool CanConvert(Type objectType) 22 | { 23 | return objectType == typeof(bool); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/BoolToStringJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Internal.Helpers.Converters 5 | { 6 | /// 7 | /// Converts to 8 | /// 9 | internal class BoolToStringJsonConverter : JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 12 | { 13 | var strValue = value != null && (bool)value == true ? "true" : "false"; 14 | writer.WriteValue(strValue); 15 | } 16 | 17 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 18 | { 19 | return reader.Value?.ToString().ToLower() == "true"; 20 | } 21 | 22 | public override bool CanConvert(Type objectType) 23 | { 24 | return objectType == typeof(bool); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/BoolToStringYNJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Internal.Helpers.Converters 5 | { 6 | /// 7 | /// Converts to 8 | /// 9 | internal class BoolToStringYNJsonConverter : JsonConverter 10 | { 11 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 12 | { 13 | var toYesNo = (bool)value == true ? "y" : "n"; 14 | writer.WriteValue(toYesNo); 15 | } 16 | 17 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 18 | { 19 | return reader.Value?.ToString() == "y"; 20 | } 21 | 22 | public override bool CanConvert(Type objectType) 23 | { 24 | return objectType == typeof(bool); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/KeyValueOrEmptyArrayConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | 6 | namespace SignNow.Net.Internal.Helpers.Converters 7 | { 8 | public class KeyValueOrEmptyArrayConverter: JsonConverter 9 | { 10 | public override bool CanConvert(Type objectType) 11 | { 12 | return objectType == typeof(Dictionary); 13 | } 14 | 15 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 16 | { 17 | if (reader.TokenType == JsonToken.StartObject) 18 | { 19 | return serializer.Deserialize>(reader); 20 | } 21 | 22 | if (reader.TokenType == JsonToken.StartArray) 23 | { 24 | JArray array = JArray.Load(reader); 25 | if (array.Count == 0) 26 | { 27 | return new Dictionary(); 28 | } 29 | } 30 | 31 | throw new JsonSerializationException("Unexpected token type: " + reader.TokenType); 32 | } 33 | 34 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 35 | { 36 | if (value is Dictionary dictionary && dictionary.Count == 0) 37 | { 38 | writer.WriteStartArray(); 39 | writer.WriteEndArray(); 40 | } 41 | else 42 | { 43 | serializer.Serialize(writer, value); 44 | } 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/StringBase64ToByteArrayJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SignNow.Net.Internal.Helpers.Converters 5 | { 6 | /// 7 | /// Converts Base64 to [] to and from JSON. 8 | /// 9 | public class StringBase64ToByteArrayJsonConverter : JsonConverter 10 | { 11 | /// 12 | public override bool CanConvert(Type objectType) 13 | { 14 | return objectType == typeof(byte[]); 15 | } 16 | 17 | /// 18 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 19 | { 20 | return Convert.FromBase64String(reader?.Value?.ToString()); 21 | } 22 | 23 | /// 24 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 25 | { 26 | writer?.WriteValue(Convert.ToBase64String((byte[])value)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/StringToBoolJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Exceptions; 5 | 6 | namespace SignNow.Net.Internal.Helpers.Converters 7 | { 8 | /// 9 | /// Converts to to and from JSON. 10 | /// 11 | internal class StringToBoolJsonConverter : JsonConverter 12 | { 13 | /// 14 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 15 | { 16 | writer.WriteValue((bool)value); 17 | } 18 | 19 | /// > 20 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, 21 | JsonSerializer serializer) 22 | { 23 | switch (reader.Value.ToString().ToUpperInvariant().Trim()) 24 | { 25 | case "TRUE": 26 | case "1": 27 | return true; 28 | case "FALSE": 29 | case "0": 30 | return false; 31 | default: 32 | throw new JsonSerializationException(string.Format( 33 | CultureInfo.CurrentCulture, ExceptionMessages.UnexpectedValueWhenConverting, 34 | objectType.Name, "`true`, `false`", 35 | reader.Value.ToString())); 36 | } 37 | } 38 | 39 | /// 40 | public override bool CanConvert(Type objectType) 41 | { 42 | return objectType == typeof(bool); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/StringToIntJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Newtonsoft.Json; 4 | 5 | namespace SignNow.Net.Internal.Helpers.Converters 6 | { 7 | /// 8 | /// Converts to to and from JSON. 9 | /// 10 | internal class StringToIntJsonConverter : JsonConverter 11 | { 12 | /// 13 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 14 | { 15 | writer.WriteValue((int)value); 16 | } 17 | 18 | /// 19 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, 20 | JsonSerializer serializer) 21 | { 22 | return int.Parse(reader.Value.ToString().Trim(), CultureInfo.InvariantCulture); 23 | } 24 | 25 | /// 26 | public override bool CanConvert(Type objectType) 27 | { 28 | return objectType == typeof(int); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/Converters/StringToUriJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Exceptions; 5 | 6 | namespace SignNow.Net.Internal.Helpers.Converters 7 | { 8 | /// 9 | /// Converts to to and from JSON. 10 | /// 11 | public class StringToUriJsonConverter : JsonConverter 12 | { 13 | /// 14 | public override bool CanConvert(Type objectType) 15 | { 16 | return objectType == typeof(Uri); 17 | } 18 | 19 | /// 20 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 21 | { 22 | if (reader?.TokenType == JsonToken.String && Uri.TryCreate(reader.Value.ToString(), UriKind.Absolute, out Uri url)) 23 | { 24 | return url; 25 | } 26 | 27 | throw new JsonSerializationException(string.Format( 28 | CultureInfo.CurrentCulture, ExceptionMessages.UnexpectedValueWhenConverting, 29 | objectType?.Name, "an absolute Url", 30 | reader?.Value?.ToString())); 31 | } 32 | 33 | /// 34 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 35 | { 36 | if (value == null) 37 | { 38 | writer?.WriteNull(); 39 | 40 | return; 41 | } 42 | 43 | writer?.WriteValue(((Uri)value).OriginalString); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Helpers/UserAgentSdkHeaders.cs: -------------------------------------------------------------------------------- 1 | using SignNow.Net.Internal.Infrastructure; 2 | 3 | namespace SignNow.Net.Internal.Helpers 4 | { 5 | /// 6 | /// Creates User-Agent string from current runtime info 7 | /// 8 | internal static class UserAgentSdkHeaders 9 | { 10 | /// 11 | /// Creates pre-formatted string with SDK, OS, Runtime information 12 | /// e.g.: client_name>/version (OS_type OS_release; platform; arch) runtime/version 13 | /// 14 | /// 15 | public static string BuildUserAgentString() 16 | { 17 | return $"{SdkRuntime.ClientName}/v{SdkRuntime.Version} " + 18 | $"({RuntimeInfo.OsName}; {RuntimeInfo.Platform}; {RuntimeInfo.Arch}) " + 19 | $"{SdkRuntime.FrameworkName()}/v{SdkRuntime.FrameworkVersion()}"; 20 | } 21 | 22 | /// 23 | /// Returns RAW runtime information with OS details. 24 | /// 25 | /// 26 | public static string RawOsDescription() 27 | { 28 | return SdkRuntime.OsDescription(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateDocumentFromTemplateRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class CreateDocumentFromTemplateRequest : JsonHttpContent 7 | { 8 | /// 9 | /// The new document name. 10 | /// 11 | [JsonProperty("document_name")] 12 | public string DocumentName { get; set; } 13 | 14 | public CreateDocumentFromTemplateRequest(string documentName) 15 | { 16 | DocumentName = documentName; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateDocumentGroupRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace SignNow.Net.Internal.Requests 7 | { 8 | internal class CreateDocumentGroupRequest : JsonHttpContent 9 | { 10 | /// 11 | /// A list of document unique ids from that Document Group will be created. 12 | /// 13 | [JsonProperty("document_ids")] 14 | public List DocumentIds { get; set; } = new List(); 15 | 16 | /// 17 | /// Name of the Document Group. 18 | /// 19 | [JsonProperty("group_name")] 20 | public string GroupName { get; set; } 21 | 22 | public CreateDocumentGroupRequest(IEnumerabledocuments) 23 | { 24 | foreach (var document in documents) 25 | { 26 | DocumentIds.Add(document.Id); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateInviteRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | public class CreateInviteRequest : JsonHttpContent 7 | { 8 | [JsonProperty("parent_id", NullValueHandling = NullValueHandling.Ignore)] 9 | public string ParentId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateOrRenameFolderRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class CreateOrRenameFolderRequest : JsonHttpContent 7 | { 8 | [JsonProperty("parent_id", NullValueHandling = NullValueHandling.Ignore)] 9 | public string ParentId { get; set; } 10 | 11 | [JsonProperty("name")] 12 | public string Name { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateSigningLinkRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class CreateSigningLinkRequest : JsonHttpContent 7 | { 8 | [JsonProperty("document_id")] 9 | public string DocumentId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/CreateTemplateFromDocumentRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class CreateTemplateFromDocumentRequest : JsonHttpContent 7 | { 8 | /// 9 | /// The new template name. 10 | /// 11 | [JsonProperty("document_name")] 12 | public string TemplateName { get; set; } 13 | 14 | /// 15 | /// ID of the document which is the source of a template 16 | /// 17 | [JsonProperty("document_id")] 18 | public string DocumentId { get; set; } 19 | 20 | public CreateTemplateFromDocumentRequest(string templateName, string documentId) 21 | { 22 | TemplateName = templateName; 23 | DocumentId = documentId; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/EditFieldRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using SignNow.Net.Interfaces; 5 | using SignNow.Net.Internal.Helpers.Converters; 6 | using SignNow.Net.Model.Requests; 7 | 8 | namespace SignNow.Net.Internal.Requests 9 | { 10 | internal class EditFieldRequest : JsonHttpContent 11 | { 12 | [JsonProperty("client_timestamp")] 13 | [JsonConverter(typeof(UnixTimeStampJsonConverter))] 14 | public DateTime ClientTime { get; set; } = DateTime.Now; 15 | 16 | [JsonProperty("fields")] 17 | public List Fields { get; set; } = new List(); 18 | 19 | public EditFieldRequest(IFieldEditable field) 20 | { 21 | Fields.Add(field); 22 | } 23 | 24 | public EditFieldRequest(IEnumerable fields) 25 | { 26 | Fields = (List)fields; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/EmbeddedSigningLinkRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using SignNow.Net.Model.Requests; 4 | 5 | namespace SignNow.Net.Internal.Requests 6 | { 7 | internal class EmbeddedSigningLinkRequest : JsonHttpContent 8 | { 9 | private CreateEmbedLinkOptions LinkOptions { get; set; } 10 | 11 | /// 12 | [JsonProperty("auth_method")] 13 | [JsonConverter(typeof(StringEnumConverter))] 14 | public EmbeddedAuthType AuthMethod => LinkOptions.AuthMethod; 15 | 16 | /// 17 | [JsonProperty("link_expiration")] 18 | public uint? LinkExpiration => LinkOptions.LinkExpiration; 19 | 20 | /// 21 | /// Embedded Signing Link Request ctor. 22 | /// 23 | /// options to create link for embedded signing. 24 | public EmbeddedSigningLinkRequest(CreateEmbedLinkOptions options) 25 | { 26 | LinkOptions = options; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/EmbeddedSigningRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using SignNow.Net.Model; 4 | using SignNow.Net.Model.Requests; 5 | 6 | namespace SignNow.Net.Internal.Requests 7 | { 8 | internal class EmbeddedSigningRequest : JsonHttpContent 9 | { 10 | /// 11 | /// Collections of request options. 12 | /// 13 | [JsonProperty("invites")] 14 | public List Invites { get; set; } = new List(); 15 | 16 | public EmbeddedSigningRequest() {} 17 | 18 | public EmbeddedSigningRequest(EmbeddedSigningInvite invite) 19 | { 20 | Invites = invite.EmbeddedSignInvites; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/MergeDocumentRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Text; 4 | using Newtonsoft.Json; 5 | using SignNow.Net.Interfaces; 6 | using SignNow.Net.Internal.Extensions; 7 | using SignNow.Net.Model; 8 | using SignNow.Net.Model.Requests; 9 | 10 | namespace SignNow.Net.Internal.Requests 11 | { 12 | internal class MergeDocumentRequest : JsonHttpContent 13 | { 14 | /// 15 | /// The name of the document that will be created and written to. 16 | /// 17 | [JsonProperty("name")] 18 | public string Name { get; set; } 19 | 20 | /// 21 | /// A list of document unique ids that will be merged. 22 | /// 23 | [JsonProperty("document_ids")] 24 | public List DocumentIds { get; set; } = new List(); 25 | 26 | /// 27 | /// Adds documents to be merged 28 | /// 29 | /// Collection of documents 30 | public void AddDocuments(IEnumerable docs) 31 | { 32 | foreach (var doc in docs) 33 | { 34 | DocumentIds.Add(doc.Id.ValidateId()); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/MoveDocumentGroupRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | public class MoveDocumentGroupRequest: JsonHttpContent 7 | { 8 | /// 9 | /// ID of the folder to move the document group to. Allowed folder types: Documents, Archive, Shared Documents folders. 10 | /// 11 | [JsonProperty("folder_id")] 12 | internal string FolderId { get; set; } 13 | 14 | /// 15 | /// Whether to move shared documents that are in this document group. With this parameter, a document group can only be moved to trash. 16 | /// 17 | [JsonProperty("with_shared_documents")] 18 | internal bool WithSharedDocuments { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/MoveDocumentRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class MoveDocumentRequest : JsonHttpContent 7 | { 8 | [JsonProperty("folder_id")] 9 | public string FolderId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/PrefillTextFieldRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Text; 4 | using Newtonsoft.Json; 5 | using SignNow.Net.Interfaces; 6 | using SignNow.Net.Model.EditFields; 7 | using SignNow.Net.Model.Requests; 8 | 9 | namespace SignNow.Net.Internal.Requests 10 | { 11 | internal class PrefillTextFieldRequest : JsonHttpContent 12 | { 13 | /// 14 | /// Collections of request options. 15 | /// 16 | [JsonProperty("fields")] 17 | internal List Fields { get; set; } = new List(); 18 | 19 | public PrefillTextFieldRequest(IEnumerable fields) 20 | { 21 | foreach (var field in fields) 22 | { 23 | Fields.Add(new PrefillText { FieldName = field.Name, PrefilledText = field.PrefilledText }); 24 | } 25 | } 26 | 27 | public PrefillTextFieldRequest(TextField field) 28 | { 29 | Fields.Add(new PrefillText { FieldName = field.Name, PrefilledText = field.PrefilledText }); 30 | } 31 | } 32 | 33 | internal class PrefillText 34 | { 35 | /// 36 | /// The unique field name that identifies the field. 37 | /// 38 | [JsonProperty("field_name")] 39 | public string FieldName { get; set; } 40 | 41 | /// 42 | /// The value that should appear on the document. 43 | /// 44 | [JsonProperty("prefilled_text")] 45 | public string PrefilledText { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/RenameDocumentGroupRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | internal class RenameDocumentGroupRequest : JsonHttpContent 7 | { 8 | [JsonProperty("group_name")] 9 | public string GroupName { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/_Internal/Requests/SendVerificationEmailRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using SignNow.Net.Model.Requests; 3 | 4 | namespace SignNow.Net.Internal.Requests 5 | { 6 | public class SendVerificationEmailRequest : JsonHttpContent 7 | { 8 | [JsonProperty("email")] 9 | public string Email { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SignNow.Net/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/signnow/SignNow.NET/7122c316be1fbcc019876f87da27f85c4af01522/SignNow.Net/icon.png -------------------------------------------------------------------------------- /SignNow.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0.0 4 | signNow 5 | signNow 6 | SignNow.NET 7 | signNow.Net is a .NET 4.6.2+ and .NET standard class library for the signNow API. (Official Library) 8 | signNow allows you to embed legally-binding e-signatures into your app, CRM or cloud storage. Send documents for signature directly from your website. Invite multiple signers to finalize contracts. Track status of your requests and download signed copies automatically. 9 | airSlate Inc. 10 | 11 | icon.png 12 | e-signature;eSign;electronic-signatures;pdf;forms;document;saas;signnow-api;api-client;REST;document management;workflow automation 13 | https://github.com/signnow/SignNow.NET 14 | MIT 15 | https://github.com/signnow/SignNow.NET 16 | Git 17 | $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../release-notes.txt")) 18 | README.md 19 | 20 | 8.0 21 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 22 | bin\Publish\ 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | notify: 3 | require_ci_to_pass: yes # require the build to pass before submitting notifications 4 | after_n_builds: 5 # how many build to wait for before submitting notifications, therefore skipping status checks 5 | 6 | coverage: 7 | precision: 2 8 | round: down 9 | range: "65...90" # custom range of coverage colors from red -> yellow -> green 10 | 11 | status: 12 | project: # measuring the overall project coverage 13 | default: 14 | enabled: yes # must be yes|true to enable this status 15 | target: 80% # specify the target coverage for each commit status 16 | threshold: 5% # Allow the coverage to drop by threshold %, and posting a success status. 17 | patch: false # https://docs.codecov.io/docs/commit-status#section-patch-status 18 | changes: false 19 | 20 | parsers: 21 | gcov: 22 | branch_detection: 23 | conditional: yes 24 | loop: yes 25 | method: no 26 | macro: no 27 | 28 | comment: 29 | layout: diff 30 | behavior: default 31 | require_changes: false 32 | -------------------------------------------------------------------------------- /release-notes.txt: -------------------------------------------------------------------------------- 1 | Release notes are available at: https://github.com/signnow/SignNow.NET/releases 2 | --------------------------------------------------------------------------------