github.com/companieshouse/insolvency-api@v0.0.0-20231024103413-440c973d9e9b/service/practitioner_service_test.go (about)

     1  package service
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/companieshouse/insolvency-api/constants"
    11  
    12  	"github.com/companieshouse/insolvency-api/mocks"
    13  	mock_dao "github.com/companieshouse/insolvency-api/mocks"
    14  	"github.com/companieshouse/insolvency-api/models"
    15  	"github.com/golang/mock/gomock"
    16  	"github.com/jarcoal/httpmock"
    17  	. "github.com/smartystreets/goconvey/convey"
    18  )
    19  
    20  func TestUnitIsValidPractitionerDetails(t *testing.T) {
    21  
    22  	Convey("Practitioner request supplied is invalid - neither email or telephone number are supplied", t, func() {
    23  		mockCtrl := gomock.NewController(t)
    24  		defer mockCtrl.Finish()
    25  
    26  		practitioner := generatePractitioner()
    27  		practitioner.TelephoneNumber = ""
    28  		practitioner.Email = ""
    29  
    30  		mockService := mock_dao.NewMockService(mockCtrl)
    31  		// Expect GetInsolvencyResource to return a valid insolvency case
    32  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
    33  
    34  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
    35  
    36  		So(err, ShouldNotBeBlank)
    37  		So(err, ShouldContainSubstring, "either telephone_number or email are required")
    38  	})
    39  
    40  	Convey("Practitioner request supplied is valid - email is supplied", t, func() {
    41  		mockCtrl := gomock.NewController(t)
    42  		defer mockCtrl.Finish()
    43  
    44  		practitioner := generatePractitioner()
    45  		practitioner.TelephoneNumber = ""
    46  
    47  		mockService := mock_dao.NewMockService(mockCtrl)
    48  		// Expect GetInsolvencyResource to return a valid insolvency case
    49  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
    50  
    51  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
    52  
    53  		So(err, ShouldBeBlank)
    54  	})
    55  
    56  	Convey("Practitioner request supplied is valid - telephone number is supplied", t, func() {
    57  		mockCtrl := gomock.NewController(t)
    58  		defer mockCtrl.Finish()
    59  
    60  		practitioner := generatePractitioner()
    61  		practitioner.Email = ""
    62  
    63  		mockService := mock_dao.NewMockService(mockCtrl)
    64  		// Expect GetInsolvencyResource to return a valid insolvency case
    65  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
    66  
    67  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
    68  
    69  		So(err, ShouldBeBlank)
    70  	})
    71  
    72  	Convey("Practitioner request supplied is invalid - telephone number is less than 10 digits", t, func() {
    73  		mockCtrl := gomock.NewController(t)
    74  		defer mockCtrl.Finish()
    75  
    76  		practitioner := generatePractitioner()
    77  		practitioner.TelephoneNumber = "07777777"
    78  
    79  		mockService := mock_dao.NewMockService(mockCtrl)
    80  		// Expect GetInsolvencyResource to return a valid insolvency case
    81  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
    82  
    83  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
    84  
    85  		So(err, ShouldNotBeBlank)
    86  		So(err, ShouldContainSubstring, "telephone_number must be 10 or 11 digits long")
    87  	})
    88  
    89  	Convey("Practitioner request supplied is invalid - telephone number is more than 11 digits", t, func() {
    90  		mockCtrl := gomock.NewController(t)
    91  		defer mockCtrl.Finish()
    92  
    93  		practitioner := generatePractitioner()
    94  		practitioner.TelephoneNumber = "077777777777"
    95  
    96  		mockService := mock_dao.NewMockService(mockCtrl)
    97  		// Expect GetInsolvencyResource to return a valid insolvency case
    98  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
    99  
   100  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   101  
   102  		So(err, ShouldNotBeBlank)
   103  		So(err, ShouldContainSubstring, "telephone_number must be 10 or 11 digits long")
   104  	})
   105  
   106  	Convey("Practitioner request supplied is invalid - telephone number does not consist solely of digits", t, func() {
   107  		mockCtrl := gomock.NewController(t)
   108  		defer mockCtrl.Finish()
   109  
   110  		practitioner := generatePractitioner()
   111  		practitioner.TelephoneNumber = "077777777OO"
   112  
   113  		mockService := mock_dao.NewMockService(mockCtrl)
   114  		// Expect GetInsolvencyResource to return a valid insolvency case
   115  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   116  
   117  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   118  
   119  		So(err, ShouldNotBeBlank)
   120  		So(err, ShouldContainSubstring, "telephone_number must start with 0 and contain only numeric characters")
   121  	})
   122  
   123  	Convey("Practitioner request supplied is invalid - telephone number does not consist solely of digits", t, func() {
   124  		mockCtrl := gomock.NewController(t)
   125  		defer mockCtrl.Finish()
   126  
   127  		practitioner := generatePractitioner()
   128  		practitioner.TelephoneNumber = "07777OO"
   129  
   130  		mockService := mock_dao.NewMockService(mockCtrl)
   131  		// Expect GetInsolvencyResource to return a valid insolvency case
   132  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   133  
   134  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   135  
   136  		So(err, ShouldNotBeBlank)
   137  		So(err, ShouldContainSubstring, "telephone_number must start with 0 and contain only numeric characters")
   138  		So(err, ShouldContainSubstring, "telephone_number must be 10 or 11 digits long")
   139  	})
   140  
   141  	Convey("Practitioner request supplied is invalid - telephone number contains spaces", t, func() {
   142  		mockCtrl := gomock.NewController(t)
   143  		defer mockCtrl.Finish()
   144  
   145  		practitioner := generatePractitioner()
   146  		practitioner.TelephoneNumber = "0777777 7777"
   147  
   148  		mockService := mock_dao.NewMockService(mockCtrl)
   149  		// Expect GetInsolvencyResource to return a valid insolvency case
   150  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   151  
   152  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   153  
   154  		So(err, ShouldNotBeBlank)
   155  		So(err, ShouldContainSubstring, "telephone_number must not contain spaces")
   156  	})
   157  
   158  	Convey("Practitioner request supplied is invalid - telephone number does not begin with 0", t, func() {
   159  		mockCtrl := gomock.NewController(t)
   160  		defer mockCtrl.Finish()
   161  
   162  		practitioner := generatePractitioner()
   163  		practitioner.TelephoneNumber = "77777777777"
   164  
   165  		mockService := mock_dao.NewMockService(mockCtrl)
   166  		// Expect GetInsolvencyResource to return a valid insolvency case
   167  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   168  
   169  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   170  
   171  		So(err, ShouldNotBeBlank)
   172  		So(err, ShouldContainSubstring, "telephone_number must start with 0 and contain only numeric characters")
   173  	})
   174  
   175  	Convey("Practitioner request supplied is invalid - first name does not match regex", t, func() {
   176  		mockCtrl := gomock.NewController(t)
   177  		defer mockCtrl.Finish()
   178  
   179  		practitioner := generatePractitioner()
   180  		practitioner.FirstName = "wr0ng"
   181  
   182  		mockService := mock_dao.NewMockService(mockCtrl)
   183  		// Expect GetInsolvencyResource to return a valid insolvency case
   184  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   185  
   186  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   187  
   188  		So(err, ShouldNotBeBlank)
   189  		So(err, ShouldContainSubstring, "the first name contains a character which is not allowed")
   190  	})
   191  
   192  	Convey("Practitioner request supplied is invalid - last name does not match regex", t, func() {
   193  		mockCtrl := gomock.NewController(t)
   194  		defer mockCtrl.Finish()
   195  
   196  		practitioner := generatePractitioner()
   197  		practitioner.LastName = "wr0ng"
   198  
   199  		mockService := mock_dao.NewMockService(mockCtrl)
   200  		// Expect GetInsolvencyResource to return a valid insolvency case
   201  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   202  
   203  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   204  
   205  		So(err, ShouldNotBeBlank)
   206  		So(err, ShouldContainSubstring, "the last name contains a character which is not allowed")
   207  	})
   208  
   209  	Convey("Practitioner request supplied is invalid - first and last name does not match regex", t, func() {
   210  		mockCtrl := gomock.NewController(t)
   211  		defer mockCtrl.Finish()
   212  
   213  		practitioner := generatePractitioner()
   214  		practitioner.FirstName = "name?"
   215  		practitioner.LastName = "wr0ng"
   216  
   217  		mockService := mock_dao.NewMockService(mockCtrl)
   218  		// Expect GetInsolvencyResource to return a valid insolvency case
   219  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   220  
   221  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   222  
   223  		So(err, ShouldNotBeBlank)
   224  		So(err, ShouldContainSubstring, "the first name contains a character which is not allowed")
   225  		So(err, ShouldContainSubstring, "the last name contains a character which is not allowed")
   226  	})
   227  
   228  	Convey("Practitioner request supplied is invalid - first and last name does not match regex and contact details missing", t, func() {
   229  		mockCtrl := gomock.NewController(t)
   230  		defer mockCtrl.Finish()
   231  
   232  		practitioner := generatePractitioner()
   233  		practitioner.FirstName = "name?"
   234  		practitioner.LastName = "wr0ng"
   235  		practitioner.Email = ""
   236  		practitioner.TelephoneNumber = ""
   237  
   238  		mockService := mock_dao.NewMockService(mockCtrl)
   239  		// Expect GetInsolvencyResource to return a valid insolvency case
   240  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   241  
   242  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   243  
   244  		So(err, ShouldNotBeBlank)
   245  		So(err, ShouldContainSubstring, "either telephone_number or email are required")
   246  		So(err, ShouldContainSubstring, "the first name contains a character which is not allowed")
   247  		So(err, ShouldContainSubstring, "the last name contains a character which is not allowed")
   248  	})
   249  
   250  	Convey("Practitioner request supplied is invalid - role supplied is incorrect for CVL case", t, func() {
   251  		mockCtrl := gomock.NewController(t)
   252  		defer mockCtrl.Finish()
   253  
   254  		practitioner := generatePractitioner()
   255  		practitioner.Role = constants.Receiver.String()
   256  
   257  		mockService := mock_dao.NewMockService(mockCtrl)
   258  		// Expect GetInsolvencyResource to return a valid insolvency case
   259  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   260  
   261  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   262  
   263  		So(err, ShouldNotBeBlank)
   264  		So(err, ShouldContainSubstring, fmt.Sprintf("the practitioner role must be "+constants.FinalLiquidator.String()+" because the insolvency case for transaction ID [%s] is of type "+constants.CVL.String(), transactionID))
   265  	})
   266  
   267  	Convey("Error retrieving insolvency case when validating practitioner", t, func() {
   268  		mockCtrl := gomock.NewController(t)
   269  		defer mockCtrl.Finish()
   270  
   271  		practitioner := generatePractitioner()
   272  		practitioner.Role = constants.Receiver.String()
   273  
   274  		mockService := mock_dao.NewMockService(mockCtrl)
   275  		// Expect GetInsolvencyResource to return an error
   276  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(models.InsolvencyResourceDao{}, fmt.Errorf("error retrieving insolvency case"))
   277  
   278  		_, err := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   279  
   280  		So(err, ShouldNotBeNil)
   281  	})
   282  
   283  	Convey("Practitioner request supplied is valid - both telephone number and email are supplied", t, func() {
   284  		mockCtrl := gomock.NewController(t)
   285  		defer mockCtrl.Finish()
   286  
   287  		practitioner := generatePractitioner()
   288  
   289  		mockService := mock_dao.NewMockService(mockCtrl)
   290  		// Expect GetInsolvencyResource to return a valid insolvency case
   291  		mockService.EXPECT().GetInsolvencyResource(gomock.Any()).Return(generateInsolvencyResource(), nil)
   292  
   293  		err, _ := ValidatePractitionerDetails(mockService, transactionID, practitioner)
   294  
   295  		So(err, ShouldBeBlank)
   296  	})
   297  }
   298  
   299  func TestUnitIsValidAppointment(t *testing.T) {
   300  	transactionID := "123"
   301  	practitionerID := "456"
   302  	apiURL := "https://api.companieshouse.gov.uk"
   303  
   304  	httpmock.Activate()
   305  	defer httpmock.DeactivateAndReset()
   306  
   307  	Convey("error getting practitioners", t, func() {
   308  		mockCtrl := gomock.NewController(t)
   309  		defer mockCtrl.Finish()
   310  
   311  		mockService := mocks.NewMockService(mockCtrl)
   312  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(nil, fmt.Errorf("err"))
   313  
   314  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   315  		validationErr, err := ValidateAppointmentDetails(mockService, generateAppointment(), transactionID, practitionerID, req)
   316  		So(err.Error(), ShouldContainSubstring, "err")
   317  		So(validationErr, ShouldBeEmpty)
   318  	})
   319  
   320  	Convey("practitioner already appointed", t, func() {
   321  		mockCtrl := gomock.NewController(t)
   322  		defer mockCtrl.Finish()
   323  
   324  		defer httpmock.Reset()
   325  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   326  
   327  		practitionersResponse := []models.PractitionerResourceDao{
   328  			{
   329  				ID: practitionerID,
   330  				Appointment: &models.AppointmentResourceDao{
   331  					AppointedOn: "2012-01-23",
   332  				},
   333  			},
   334  		}
   335  		mockService := mocks.NewMockService(mockCtrl)
   336  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   337  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   338  
   339  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   340  		validationErrs, err := ValidateAppointmentDetails(mockService, generateAppointment(), transactionID, practitionerID, req)
   341  		So(err, ShouldBeNil)
   342  		So(validationErrs, ShouldContainSubstring, "already appointed")
   343  	})
   344  
   345  	Convey("error retrieving insolvency resource", t, func() {
   346  		mockCtrl := gomock.NewController(t)
   347  		defer mockCtrl.Finish()
   348  
   349  		practitionersResponse := []models.PractitionerResourceDao{
   350  			{
   351  				ID: practitionerID,
   352  				Appointment: &models.AppointmentResourceDao{
   353  					AppointedOn: "2012-01-23",
   354  				},
   355  			},
   356  		}
   357  		mockService := mocks.NewMockService(mockCtrl)
   358  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   359  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(models.InsolvencyResourceDao{}, fmt.Errorf("err"))
   360  
   361  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   362  		validationErr, err := ValidateAppointmentDetails(mockService, generateAppointment(), transactionID, practitionerID, req)
   363  		So(err.Error(), ShouldContainSubstring, "err")
   364  		So(validationErr, ShouldBeEmpty)
   365  	})
   366  
   367  	Convey("error retrieving company details", t, func() {
   368  		mockCtrl := gomock.NewController(t)
   369  		defer mockCtrl.Finish()
   370  
   371  		defer httpmock.Reset()
   372  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusTeapot, ""))
   373  
   374  		practitionersResponse := []models.PractitionerResourceDao{
   375  			{
   376  				ID: practitionerID,
   377  				Appointment: &models.AppointmentResourceDao{
   378  					AppointedOn: "2012-01-23",
   379  				},
   380  			},
   381  		}
   382  		mockService := mocks.NewMockService(mockCtrl)
   383  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   384  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   385  
   386  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   387  		validationErr, err := ValidateAppointmentDetails(mockService, generateAppointment(), transactionID, practitionerID, req)
   388  		So(validationErr, ShouldBeEmpty)
   389  		So(err.Error(), ShouldContainSubstring, "error getting company details from DB")
   390  	})
   391  
   392  	Convey("error parsing appointedOn date", t, func() {
   393  		mockCtrl := gomock.NewController(t)
   394  		defer mockCtrl.Finish()
   395  
   396  		defer httpmock.Reset()
   397  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   398  
   399  		practitionersResponse := []models.PractitionerResourceDao{
   400  			{
   401  				ID: practitionerID,
   402  				Appointment: &models.AppointmentResourceDao{
   403  					AppointedOn: "2012-01-23",
   404  				},
   405  			},
   406  		}
   407  		mockService := mocks.NewMockService(mockCtrl)
   408  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   409  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   410  
   411  		appointment := generateAppointment()
   412  		appointment.AppointedOn = "2001/1/2"
   413  
   414  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   415  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, practitionerID, req)
   416  		So(validationErr, ShouldBeEmpty)
   417  		So(err.Error(), ShouldContainSubstring, "error parsing date")
   418  	})
   419  
   420  	Convey("error parsing incorporatedOn date", t, func() {
   421  		mockCtrl := gomock.NewController(t)
   422  		defer mockCtrl.Finish()
   423  
   424  		defer httpmock.Reset()
   425  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("error")))
   426  
   427  		practitionersResponse := []models.PractitionerResourceDao{
   428  			{
   429  				ID: practitionerID,
   430  				Appointment: &models.AppointmentResourceDao{
   431  					AppointedOn: "2012-01-23",
   432  				},
   433  			},
   434  		}
   435  		mockService := mocks.NewMockService(mockCtrl)
   436  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   437  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   438  
   439  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   440  		validationErr, err := ValidateAppointmentDetails(mockService, generateAppointment(), transactionID, practitionerID, req)
   441  		So(validationErr, ShouldBeEmpty)
   442  		So(err.Error(), ShouldContainSubstring, "error parsing date")
   443  	})
   444  
   445  	Convey("invalid appointedOn date - in the future", t, func() {
   446  		mockCtrl := gomock.NewController(t)
   447  		defer mockCtrl.Finish()
   448  
   449  		defer httpmock.Reset()
   450  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   451  
   452  		practitionersResponse := []models.PractitionerResourceDao{
   453  			{
   454  				ID: practitionerID,
   455  				Appointment: &models.AppointmentResourceDao{
   456  					AppointedOn: "2012-01-23",
   457  				},
   458  			},
   459  		}
   460  		mockService := mocks.NewMockService(mockCtrl)
   461  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   462  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   463  
   464  		appointment := generateAppointment()
   465  		appointment.AppointedOn = time.Now().AddDate(0, 0, 1).Format("2006-01-02")
   466  
   467  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   468  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, "111", req)
   469  		So(validationErr, ShouldContainSubstring, "should not be in the future")
   470  		So(err, ShouldBeNil)
   471  	})
   472  
   473  	Convey("invalid appointedOn date - before company was incorporated", t, func() {
   474  		mockCtrl := gomock.NewController(t)
   475  		defer mockCtrl.Finish()
   476  
   477  		defer httpmock.Reset()
   478  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   479  
   480  		practitionersResponse := []models.PractitionerResourceDao{
   481  			{
   482  				ID: practitionerID,
   483  				Appointment: &models.AppointmentResourceDao{
   484  					AppointedOn: "2012-01-23",
   485  				},
   486  			},
   487  		}
   488  		mockService := mocks.NewMockService(mockCtrl)
   489  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   490  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   491  
   492  		appointment := generateAppointment()
   493  		appointment.AppointedOn = "1999-01-01"
   494  
   495  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   496  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, "111", req)
   497  		So(validationErr, ShouldContainSubstring, "before the company was incorporated")
   498  		So(err, ShouldBeNil)
   499  	})
   500  
   501  	Convey("invalid appointedOn date - different from already appointed practitioners", t, func() {
   502  		mockCtrl := gomock.NewController(t)
   503  		defer mockCtrl.Finish()
   504  
   505  		defer httpmock.Reset()
   506  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   507  
   508  		practitionersResponse := []models.PractitionerResourceDao{
   509  			{
   510  				ID: practitionerID,
   511  				Appointment: &models.AppointmentResourceDao{
   512  					AppointedOn: "2012-01-23",
   513  				},
   514  			},
   515  		}
   516  		mockService := mocks.NewMockService(mockCtrl)
   517  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   518  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   519  
   520  		appointment := generateAppointment()
   521  		appointment.AppointedOn = "2012-01-24"
   522  
   523  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   524  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, "111", req)
   525  		So(validationErr, ShouldEqual, fmt.Sprintf("appointed_on [%s] differs from practitioner ID [%s] who was appointed on [%s]", appointment.AppointedOn, practitionerID, practitionersResponse[0].Appointment.AppointedOn))
   526  		So(err, ShouldBeNil)
   527  	})
   528  
   529  	Convey("invalid madeBy - creditors madeBy not supplied for CVL case", t, func() {
   530  		mockCtrl := gomock.NewController(t)
   531  		defer mockCtrl.Finish()
   532  
   533  		defer httpmock.Reset()
   534  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   535  
   536  		practitionersResponse := []models.PractitionerResourceDao{
   537  			{
   538  				ID: practitionerID,
   539  				Appointment: &models.AppointmentResourceDao{
   540  					AppointedOn: "2012-01-23",
   541  				},
   542  			},
   543  		}
   544  		mockService := mocks.NewMockService(mockCtrl)
   545  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   546  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   547  
   548  		appointment := generateAppointment()
   549  		appointment.MadeBy = "company"
   550  
   551  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   552  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, "111", req)
   553  		So(validationErr, ShouldEqual, fmt.Sprintf("made_by cannot be [%s] for insolvency case of type CVL", appointment.MadeBy))
   554  		So(err, ShouldBeNil)
   555  	})
   556  
   557  	Convey("valid appointment", t, func() {
   558  		mockCtrl := gomock.NewController(t)
   559  		defer mockCtrl.Finish()
   560  
   561  		defer httpmock.Reset()
   562  		httpmock.RegisterResponder(http.MethodGet, apiURL+"/company/1234", httpmock.NewStringResponder(http.StatusOK, companyProfileDateResponse("2000-06-26 00:00:00.000Z")))
   563  
   564  		practitionersResponse := []models.PractitionerResourceDao{
   565  			{
   566  				ID: practitionerID,
   567  				Appointment: &models.AppointmentResourceDao{
   568  					AppointedOn: "2012-01-23",
   569  				},
   570  			},
   571  		}
   572  		mockService := mocks.NewMockService(mockCtrl)
   573  		mockService.EXPECT().GetPractitionerResources(gomock.Any()).Return(practitionersResponse, nil)
   574  		mockService.EXPECT().GetInsolvencyResource(transactionID).Return(generateInsolvencyResource(), nil)
   575  
   576  		appointment := generateAppointment()
   577  		appointment.MadeBy = "creditors"
   578  
   579  		req := httptest.NewRequest(http.MethodGet, "/", nil)
   580  		validationErr, err := ValidateAppointmentDetails(mockService, appointment, transactionID, "111", req)
   581  		So(validationErr, ShouldBeEmpty)
   582  		So(err, ShouldBeNil)
   583  	})
   584  
   585  }
   586  
   587  func generatePractitioner() models.PractitionerRequest {
   588  	return models.PractitionerRequest{
   589  		IPCode:          "1234",
   590  		FirstName:       "Joe",
   591  		LastName:        "Bloggs",
   592  		TelephoneNumber: "01234567890",
   593  		Email:           "a@b.com",
   594  		Address: models.Address{
   595  			AddressLine1: "addressline1",
   596  			Locality:     "locality",
   597  		},
   598  		Role: constants.FinalLiquidator.String(),
   599  	}
   600  }
   601  
   602  func generateAppointment() models.PractitionerAppointment {
   603  	return models.PractitionerAppointment{
   604  		AppointedOn: "2012-01-23",
   605  		MadeBy:      "creditors",
   606  	}
   607  }
   608  
   609  func generateInsolvencyResource() models.InsolvencyResourceDao {
   610  	return models.InsolvencyResourceDao{
   611  		Data: models.InsolvencyResourceDaoData{
   612  			CompanyNumber: "1234",
   613  			CaseType:      "creditors-voluntary-liquidation",
   614  			CompanyName:   "Company",
   615  			Practitioners: []models.PractitionerResourceDao{
   616  				{
   617  					ID:              "1234",
   618  					IPCode:          "1111",
   619  					FirstName:       "First",
   620  					LastName:        "Last",
   621  					TelephoneNumber: "12345678901",
   622  					Email:           "email@email.com",
   623  					Address:         models.AddressResourceDao{},
   624  					Role:            "role",
   625  					Links:           models.PractitionerResourceLinksDao{},
   626  					Appointment:     nil,
   627  				},
   628  			},
   629  		},
   630  	}
   631  }
   632  
   633  func companyProfileDateResponse(dateOfCreation string) string {
   634  	return `
   635  {
   636   "company_name": "companyName",
   637   "company_number": "01234567",
   638   "jurisdiction": "england-wales",
   639   "company_status": "active",
   640   "type": "private-shares-exemption-30",
   641   "date_of_creation": "` + dateOfCreation + `",
   642   "registered_office_address" : {
   643     "postal_code" : "CF14 3UZ",
   644     "address_line_2" : "Cardiff",
   645     "address_line_1" : "1 Crown Way"
   646    }
   647  }
   648  `
   649  
   650  }