using System; using Xunit; using Newtonsoft.Json.Linq; using FluentAssertions; using System.Collections.Generic; using System.Collections.Concurrent; using System.Net.Http; using System.Net.Http.Headers; using System.IO; namespace raven_integration { //https://stackoverflow.com/questions/17725882/testing-asp-net-web-api-multipart-form-data-file-upload public class AttachmentTest { /// /// test attach CRUD /// [Fact] public async void AttachmentUploadDownloadDeleteShouldWork() { //Make a user just for this test so can deal with dl token properly var UniqueName = Util.Uniquify("AttachmentUploadDownloadDeleteShouldWork"); //CREATE dynamic d = new JObject(); d.name = UniqueName; d.active = true; d.login = UniqueName; d.password = UniqueName; d.roles = 2;//bizadminfull needs widget rights d.userType = 3;//non scheduleable //Required by form custom rules d.notes = "notes"; d.customFields = Util.UserRequiredCustomFieldsJsonString(); ApiResponse a = await Util.PostAsync("User", await Util.GetTokenAsync("superuser", "l3tm3in"), d.ToString()); Util.ValidateDataReturnResponseOk(a); long TestUserId=a.ObjectResponse["data"]["id"].Value(); d = new JObject(); d.login = UniqueName; d.password = UniqueName; a = await Util.PostAsync("auth", null, d.ToString()); string downloadToken = a.ObjectResponse["data"]["dlt"].Value(); ////////////////////////////////////////// //// Upload the files MultipartFormDataContent formDataContent = new MultipartFormDataContent(); //Form data like the bizobject type and id formDataContent.Add(new StringContent("3"), name: "AttachToObjectType"); formDataContent.Add(new StringContent(TestUserId.ToString()), name: "AttachToObjectId"); formDataContent.Add(new StringContent("Test:AttachmentUploadDownloadDeleteShouldWork"), name: "Notes"); formDataContent.Add(new StringContent("[{\"name\":\"test.zip\",\"lastModified\":1582822079618},{\"name\":\"test.png\",\"lastModified\":1586900220990}]"), name: "FileData"); //fileData in JSON stringify format which contains the actual last modified dates etc //"[{\"name\":\"Client.csv\",\"lastModified\":1582822079618},{\"name\":\"wmi4fu06nrs41.jpg\",\"lastModified\":1586900220990}]" //or if testing non-existant this is probably safe: long.MaxValue StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); file1.Headers.ContentDisposition.FileName = "test.png"; formDataContent.Add(file1); StreamContent file2 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.zip")); file2.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); file2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); file2.Headers.ContentDisposition.FileName = "test.zip"; formDataContent.Add(file2); //create via inventory full test user as attachments use the role of the object attaching to a = await Util.PostFormDataAsync("attachment", formDataContent, await Util.GetTokenAsync("superuser", "l3tm3in")); Util.ValidateDataReturnResponseOk(a); long lTestPngAttachmentId = a.ObjectResponse["data"][0]["id"].Value(); long lTestZipAttachmentId = a.ObjectResponse["data"][1]["id"].Value(); //saw negative values on a db issue that I corrected (I think) //Keeping these in case it arises again, if it does, see log, it's a db error with async issue of some kind lTestPngAttachmentId.Should().BePositive(); lTestZipAttachmentId.Should().BePositive(); ////////////////////////////////////////// //// DOWNLOAD: Get the file attachment //now get the file https://rockfish.ayanova.com/api/rfcaseblob/download/248?t=9O2eDAAlZ0Wknj19SBK2iA var dlresponse = await Util.DownloadFileAsync("attachment/Download/" + lTestZipAttachmentId.ToString() + "?t=" + downloadToken, null); //ensure it's the zip file we expected dlresponse.Content.Headers.ContentDisposition.FileName.Should().Be("test.zip"); dlresponse.Content.Headers.ContentLength.Should().BeGreaterThan(2000); ////////////////////////////////////////// //// DELETE: Delete the file attachments a = await Util.DeleteAsync("attachment/" + lTestPngAttachmentId.ToString(), await Util.GetTokenAsync("superuser", "l3tm3in")); Util.ValidateHTTPStatusCode(a, 204); a = await Util.DeleteAsync("attachment/" + lTestZipAttachmentId.ToString(), await Util.GetTokenAsync("superuser", "l3tm3in")); Util.ValidateHTTPStatusCode(a, 204); } /// /// test no rights /// [Fact] public async void NoRightsTest() { MultipartFormDataContent formDataContent = new MultipartFormDataContent(); formDataContent.Add(new StringContent("2"), name: "AttachToObjectType"); formDataContent.Add(new StringContent("1"), name: "AttachToObjectId"); formDataContent.Add(new StringContent("Test:AttachmentUploadDownloadDeleteShouldWork"), name: "Notes"); formDataContent.Add(new StringContent("[{\"name\":\"test.png\",\"lastModified\":1586900220990}]"), name: "FileData"); StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); file1.Headers.ContentDisposition.FileName = "test.png"; formDataContent.Add(file1); //ERROR CONDITION: BizAdminLimited user should not be able to attach a file to a widget ApiResponse a = await Util.PostFormDataAsync("attachment", formDataContent, await Util.GetTokenAsync("BizAdminLimited")); //2004 unauthorized Util.ValidateErrorCodeResponse(a, 2004, 403); } /// /// test not attachable /// [Fact] public async void UnattachableTest() { MultipartFormDataContent formDataContent = new MultipartFormDataContent(); //Form data bizobject type and id //HERE IS THE ERROR CONDITION: LICENSE TYPE OBJECT WHICH IS UNATTACHABLE formDataContent.Add(new StringContent("5"), name: "AttachToObjectType"); formDataContent.Add(new StringContent("1"), name: "AttachToObjectId"); StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); file1.Headers.ContentDisposition.FileName = "test.png"; formDataContent.Add(file1); ApiResponse a = await Util.PostFormDataAsync("attachment", formDataContent, await Util.GetTokenAsync("InventoryFull")); //2203 unattachable object Util.ValidateErrorCodeResponse(a, 2203, 400); } /// /// test bad object values /// [Fact] public async void BadObject() { MultipartFormDataContent formDataContent = new MultipartFormDataContent(); //Form data like the bizobject type and id formDataContent.Add(new StringContent("2"), name: "AttachToObjectType"); //HERE IS THE ERROR CONDITION, A NON EXISTENT ID VALUE FOR THE WIDGET formDataContent.Add(new StringContent(long.MaxValue.ToString()), name: "AttachToObjectId");//non-existent widget StreamContent file1 = new StreamContent(File.OpenRead($"{Util.TEST_DATA_FOLDER}\\test.png")); file1.Headers.ContentType = new MediaTypeHeaderValue("image/png"); file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); file1.Headers.ContentDisposition.FileName = "test.png"; formDataContent.Add(file1); ApiResponse a = await Util.PostFormDataAsync("attachment", formDataContent, await Util.GetTokenAsync("InventoryFull")); //2203 invalid attachment object Util.ValidateErrorCodeResponse(a, 2203, 400); } //================================================== }//eoc }//eons