Code like a Unit Tester

On Tuesday night (2019\05\14) I did a presentation at the Developer User Group. My talk was titled Code like a Unit Tester and focused on the different coding style required to write code that can be unit tested. Overall the presentation took about 7 minutes and I had a good few chats afterwards with people interested in improving their skills in the unit testing area.

weworkremotely.com

With my wife potentially being seconded to another African country I decided that I need to look for a job where I can work remotely. If she does get seconded I can travel with her.

 

On a podcast I heard about a site that only advertises jobs where you can work remotely

http://weworkremotely.com

 

Learning React

Most of the jobs I see that I would like to apply for require a developer to know React. In my quest to learn react I came across this summary course on YouTube. If you are like me and find normal training boring this summary course will be of interest. (It is actually an advert for his longer paid course).

Agile for Solo Developers

For a long time I have been thinking how Agile can help solo developers become more organized. I do a lot of projects on my own and effectively use an Agile methodology but have never really formalized it.

Key areas I have been thinking about are

  • Requirements Gathering
  • Sprints
  • Retrospectives
  • Testing Automation
  • Deployment (DevOps)

A simple example of what I am thinking about is: The Sprint Daily Standup – how do you do a standup if you are working alone, there is no scrum master to remove impediments. The Daily stand up therefore becomes a daily retrospective and planning session. Each day look at what was done, work out if it was DoD, and plan the next day.

I also want to add in ideas on how to document the different Agile ceremonies so that lightweight documentation is deliver to allow an Audit of progress.

I have also realized there are at least 3 different types of work I do solo and each may require a different solo methodology. I call these

  1. Building – churning out code on a reasonably well understood problem area
  2. Hunting – Error solving and bug smashing. Often as part of Building but also as a support process
  3. Exploration – Got a new idea, or a new tool. Taking the time to learn the tool or resolve the new idea.

C# loading a file through Ajax and Web API

This information was mostly sourced from:

https://www.c-sharpcorner.com/UploadFile/manas1/upload-files-through-jquery-ajax-in-Asp-Net-mvc/

 

The Modal Form

<div id="AddFileDialog" class="modal">

<!-- Modal content -->
<div class="modalcontent">
  <div class="modalheader">
    <span class="close" onclick="cancelAddFileDialogClick();" id="closeAddFileDialog">&times;</span>
    <h1>Add File</h1>
  </div>
  <div class="modalbody">
    <form id="NewsForm">
      <input type="hidden" id="FAAuctionID" />
      <div class="form-group has-feedback">
        <label for="FAAuctionName">Auction</label>
        <input type="input" name="FAAuctionName" id="FAAuctionName" value="" placeholder="Enter Auction Name" autocomplete="off" class="form-control" disabled>
      </div>
      <div class="form-group has-feedback">
        <label for="FileType">File Type</label>
        <select name="FileType" id="FileType" class="form-control">
          <option value="1">Image</option>
          <option value="2">Document</option>
        </select>
      </div>
      <div class="form-group has-feedback">
        <label for="FileName">Name</label>
        <input type="input" name="FileName" id="FileName" value="" placeholder="Enter Descriptive Name" autocomplete="off" class="form-control">
      </div>
      <div class="form-group has-feedback">
        <label for="Files">File</label>
        <input type="file" name="Files" id="Files" class="form-control"></input>
      </div>
    </form>
  </div>
  <div class="modalfooter">
    <a href="#" class="btn btn-primary" onclick="OKAddFileDialogClick();" id="OKAddFileDialog">OK</a>
    <a href="#" class="btn btn-primary" onclick="cancelAddFileDialogClick();" id="cancelAddFileDialog">Cancel</a>
  </div>
</div>

</div>

Java Script Show Form

                                        $("#FAAuctionID").val(data.record.id);
                                        $("#FAAuctionName").val(data.record.Name);
                                        $("#AddFileDialog").show();


JavaScript Dialog Management and send to server

function cancelAddFileDialogClick() {
    $("#AddFileDialog").hide();
}

function OKAddFileDialogClick() {
    // Link Companies in group to Auction
    AuctionID = $("#FAAuctionID").val();
    FileType = $("#FileType").val();
    FileName = $("#FileName").val();
    var fileData = new FormData();
    var fileUpload = $("#Files").get(0);
    var files = fileUpload.files;
    for (var i = 0; i < files.length; i++) {
        fileData.append(files[i].name, files[i]);
    }
    fileData.append("AuctionID", AuctionID);
    fileData.append("FileType", FileType);
    fileData.append("Name", FileName);
    $.ajax({
        method: "POST",
        contentType: false,   
        processData: false,
        beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', 'Bearer ' + LoadToken(TokenName)) },
        url: "/api/Auctions/File/Create",
        data: fileData
    })
    .done(function (data) {
        if (data.Result == "OK") {
            alert("File Linked successfully.");
            $("#AddFileDialog").hide();
        }
        if (data.status == "ERROR") {
            alert(data.message);
        }
    })
    .fail(function (data) {
        alert(data.responseText);
    });
}

C# code in ApiController

[Route("api/Auctions/File/Create")]
        [HttpPost]
        public HttpResponseMessage UploadFiles()
        {
            // Checking no of files injected in Request object  
            if (System.Web.HttpContext.Current.Request.Files.Count > 0)
            {
                List<Models.AuctionFile> OutFiles = new List<Models.AuctionFile>();
                try
                {
                    //  Get all files from Request object  
                    HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;
                    for (int i = 0; i < files.Count; i++)
                    {
                        //string path = AppDomain.CurrentDomain.BaseDirectory + "Uploads/";  
                        //string filename = Path.GetFileName(Request.Files[i].FileName);  

                        HttpPostedFile file = files[i];
                        string fname;

                        // Checking for Internet Explorer  
                        if (System.Web.HttpContext.Current.Request.Browser.Browser.ToUpper() == "IE" || System.Web.HttpContext.Current.Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
                        {
                            string[] testfiles = file.FileName.Split(new char[] { '\\' });
                            fname = testfiles[testfiles.Length - 1];
                        }
                        else
                        {
                            fname = file.FileName;
                        }
                        fname = Path.GetFileName(fname); // Drop path of uploaded file

                        // Get the complete folder path and store the file inside it.  
                        fname = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/Uploads/"), fname);
                        file.SaveAs(fname);
                        // TODO: Link in Database

                        AuctionFile Model = new AuctionFile();
                        Model.CreatedBy = UserHelper.currentUser(this);
                        Model.CreatedDate = DateTime.Now;
                        Model.AuctionID = Int32.Parse(System.Web.HttpContext.Current.Request.Params["AuctionID"]);
                        Model.FileType = Int32.Parse(System.Web.HttpContext.Current.Request.Params["FileType"]);
                        Model.Name = System.Web.HttpContext.Current.Request.Params["Name"];
                        Model.Path = fname;
                        db.AuctionFile.Add(Model);
                        // Done: Create Audit
                        CreateAudit(Model);
                        db.SaveChanges();
                        OutFiles.Add(Model);               
                    }
                    // Returns message that successfully uploaded  
                    return Request.CreateResponse(HttpStatusCode.OK, new { Result = "OK", Records = OutFiles, TotalRecordCount = OutFiles.Count() });
                }
                catch (Exception ex)
                {
                    return Request.CreateResponse(HttpStatusCode.OK, new { Result = "ERROR", Message = ex.Message });
                }
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.OK, new { Result = "ERROR", Message = "No files Selected" });
            }
        }