github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/cf/commands/route/unmap_route_test.go (about)

     1  package route_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/cf/commandregistry"
     7  	"code.cloudfoundry.org/cli/cf/commands/route"
     8  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
     9  	"code.cloudfoundry.org/cli/cf/flags"
    10  	"code.cloudfoundry.org/cli/cf/models"
    11  	"code.cloudfoundry.org/cli/cf/requirements"
    12  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    13  
    14  	"code.cloudfoundry.org/cli/cf/api/apifakes"
    15  
    16  	testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration"
    17  	testterm "code.cloudfoundry.org/cli/cf/util/testhelpers/terminal"
    18  
    19  	"strings"
    20  
    21  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("UnmapRoute", func() {
    27  	var (
    28  		ui         *testterm.FakeUI
    29  		configRepo coreconfig.Repository
    30  		routeRepo  *apifakes.FakeRouteRepository
    31  
    32  		cmd         commandregistry.Command
    33  		deps        commandregistry.Dependency
    34  		factory     *requirementsfakes.FakeFactory
    35  		flagContext flags.FlagContext
    36  
    37  		loginRequirement       requirements.Requirement
    38  		applicationRequirement *requirementsfakes.FakeApplicationRequirement
    39  		domainRequirement      *requirementsfakes.FakeDomainRequirement
    40  
    41  		fakeDomain models.DomainFields
    42  	)
    43  
    44  	BeforeEach(func() {
    45  		ui = &testterm.FakeUI{}
    46  		configRepo = testconfig.NewRepositoryWithDefaults()
    47  		routeRepo = new(apifakes.FakeRouteRepository)
    48  		repoLocator := deps.RepoLocator.SetRouteRepository(routeRepo)
    49  
    50  		deps = commandregistry.Dependency{
    51  			UI:          ui,
    52  			Config:      configRepo,
    53  			RepoLocator: repoLocator,
    54  		}
    55  
    56  		cmd = &route.UnmapRoute{}
    57  		cmd.SetDependency(deps, false)
    58  
    59  		flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
    60  
    61  		factory = new(requirementsfakes.FakeFactory)
    62  
    63  		loginRequirement = &passingRequirement{Name: "login-requirement"}
    64  		factory.NewLoginRequirementReturns(loginRequirement)
    65  
    66  		applicationRequirement = new(requirementsfakes.FakeApplicationRequirement)
    67  		factory.NewApplicationRequirementReturns(applicationRequirement)
    68  
    69  		fakeApplication := models.Application{}
    70  		fakeApplication.GUID = "fake-app-guid"
    71  		applicationRequirement.GetApplicationReturns(fakeApplication)
    72  
    73  		domainRequirement = new(requirementsfakes.FakeDomainRequirement)
    74  		factory.NewDomainRequirementReturns(domainRequirement)
    75  
    76  		fakeDomain = models.DomainFields{
    77  			GUID: "fake-domain-guid",
    78  			Name: "fake-domain-name",
    79  		}
    80  		domainRequirement.GetDomainReturns(fakeDomain)
    81  	})
    82  
    83  	Describe("Help text", func() {
    84  		var usage []string
    85  
    86  		BeforeEach(func() {
    87  			cmd := &route.UnmapRoute{}
    88  			up := commandregistry.CLICommandUsagePresenter(cmd)
    89  
    90  			usage = strings.Split(up.Usage(), "\n")
    91  		})
    92  
    93  		It("contains an example", func() {
    94  			Expect(usage).To(ContainElement("   cf unmap-route my-app example.com --port 5000                  # example.com:5000"))
    95  		})
    96  
    97  		It("contains the options", func() {
    98  			Expect(usage).To(ContainElement("   --hostname, -n      Hostname used to identify the HTTP route"))
    99  			Expect(usage).To(ContainElement("   --path              Path used to identify the HTTP route"))
   100  			Expect(usage).To(ContainElement("   --port              Port used to identify the TCP route"))
   101  		})
   102  
   103  		It("shows the usage", func() {
   104  			Expect(usage).To(ContainElement("   Unmap an HTTP route:"))
   105  			Expect(usage).To(ContainElement("      cf unmap-route APP_NAME DOMAIN [--hostname HOSTNAME] [--path PATH]"))
   106  
   107  			Expect(usage).To(ContainElement("   Unmap a TCP route:"))
   108  			Expect(usage).To(ContainElement("      cf unmap-route APP_NAME DOMAIN --port PORT"))
   109  		})
   110  	})
   111  
   112  	Describe("Requirements", func() {
   113  		Context("when not provided exactly two args", func() {
   114  			BeforeEach(func() {
   115  				flagContext.Parse("app-name")
   116  			})
   117  
   118  			It("fails with usage", func() {
   119  				_, err := cmd.Requirements(factory, flagContext)
   120  				Expect(err).To(HaveOccurred())
   121  				Expect(ui.Outputs()).To(ContainSubstrings(
   122  					[]string{"Incorrect Usage. Requires app_name, domain_name as arguments"},
   123  					[]string{"NAME"},
   124  					[]string{"USAGE"},
   125  				))
   126  			})
   127  		})
   128  
   129  		Context("when provided exactly two args", func() {
   130  			BeforeEach(func() {
   131  				flagContext.Parse("app-name", "domain-name")
   132  			})
   133  
   134  			It("returns a LoginRequirement", func() {
   135  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   136  				Expect(err).NotTo(HaveOccurred())
   137  				Expect(factory.NewLoginRequirementCallCount()).To(Equal(1))
   138  
   139  				Expect(actualRequirements).To(ContainElement(loginRequirement))
   140  			})
   141  
   142  			It("returns an ApplicationRequirement", func() {
   143  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   144  				Expect(err).NotTo(HaveOccurred())
   145  				Expect(factory.NewApplicationRequirementCallCount()).To(Equal(1))
   146  
   147  				Expect(factory.NewApplicationRequirementArgsForCall(0)).To(Equal("app-name"))
   148  				Expect(actualRequirements).To(ContainElement(applicationRequirement))
   149  			})
   150  
   151  			It("returns a DomainRequirement", func() {
   152  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   153  				Expect(err).NotTo(HaveOccurred())
   154  				Expect(factory.NewDomainRequirementCallCount()).To(Equal(1))
   155  
   156  				Expect(factory.NewDomainRequirementArgsForCall(0)).To(Equal("domain-name"))
   157  				Expect(actualRequirements).To(ContainElement(domainRequirement))
   158  			})
   159  
   160  			Context("when passing port with a hostname", func() {
   161  				BeforeEach(func() {
   162  					flagContext.Parse("app-name", "example.com", "--port", "8080", "--hostname", "something-else")
   163  				})
   164  
   165  				It("fails", func() {
   166  					_, err := cmd.Requirements(factory, flagContext)
   167  					Expect(err).To(HaveOccurred())
   168  					Expect(ui.Outputs()).To(ContainSubstrings(
   169  						[]string{"FAILED"},
   170  						[]string{"Cannot specify port together with hostname and/or path."},
   171  					))
   172  				})
   173  			})
   174  
   175  			Context("when passing port with a path", func() {
   176  				BeforeEach(func() {
   177  					flagContext.Parse("app-name", "example.com", "--port", "8080", "--path", "something-else")
   178  				})
   179  
   180  				It("fails", func() {
   181  					_, err := cmd.Requirements(factory, flagContext)
   182  					Expect(err).To(HaveOccurred())
   183  					Expect(ui.Outputs()).To(ContainSubstrings(
   184  						[]string{"FAILED"},
   185  						[]string{"Cannot specify port together with hostname and/or path."},
   186  					))
   187  				})
   188  			})
   189  		})
   190  	})
   191  
   192  	Describe("Execute", func() {
   193  		var err error
   194  
   195  		BeforeEach(func() {
   196  			err := flagContext.Parse("app-name", "domain-name")
   197  			Expect(err).NotTo(HaveOccurred())
   198  			cmd.Requirements(factory, flagContext)
   199  		})
   200  
   201  		JustBeforeEach(func() {
   202  			err = cmd.Execute(flagContext)
   203  		})
   204  
   205  		It("tries to find the route", func() {
   206  			Expect(err).NotTo(HaveOccurred())
   207  			Expect(routeRepo.FindCallCount()).To(Equal(1))
   208  			hostname, domain, path, port := routeRepo.FindArgsForCall(0)
   209  			Expect(hostname).To(Equal(""))
   210  			Expect(domain).To(Equal(fakeDomain))
   211  			Expect(path).To(Equal(""))
   212  			Expect(port).To(Equal(0))
   213  		})
   214  
   215  		Context("when a path is passed", func() {
   216  			BeforeEach(func() {
   217  				err := flagContext.Parse("app-name", "domain-name", "--path", "the-path")
   218  				Expect(err).NotTo(HaveOccurred())
   219  				cmd.Requirements(factory, flagContext)
   220  			})
   221  
   222  			It("tries to find the route with the path", func() {
   223  				Expect(err).NotTo(HaveOccurred())
   224  				Expect(routeRepo.FindCallCount()).To(Equal(1))
   225  				_, _, path, _ := routeRepo.FindArgsForCall(0)
   226  				Expect(path).To(Equal("the-path"))
   227  			})
   228  		})
   229  
   230  		Context("when a port is passed", func() {
   231  			BeforeEach(func() {
   232  				err := flagContext.Parse("app-name", "domain-name", "--port", "60000")
   233  				Expect(err).NotTo(HaveOccurred())
   234  				cmd.Requirements(factory, flagContext)
   235  			})
   236  
   237  			It("tries to find the route with the port", func() {
   238  				Expect(err).NotTo(HaveOccurred())
   239  				Expect(routeRepo.FindCallCount()).To(Equal(1))
   240  				_, _, _, port := routeRepo.FindArgsForCall(0)
   241  				Expect(port).To(Equal(60000))
   242  			})
   243  		})
   244  
   245  		Context("when the route can be found", func() {
   246  			BeforeEach(func() {
   247  				routeRepo.FindReturns(models.Route{GUID: "route-guid"}, nil)
   248  			})
   249  
   250  			It("tells the user that it is removing the route", func() {
   251  				Expect(err).NotTo(HaveOccurred())
   252  				Expect(ui.Outputs()).To(ContainSubstrings(
   253  					[]string{"Removing route", "from app", "in org"},
   254  				))
   255  			})
   256  
   257  			Context("when the returned route has an app with the requested app's guid", func() {
   258  				BeforeEach(func() {
   259  					route := models.Route{
   260  						GUID: "route-guid",
   261  						Apps: []models.ApplicationFields{
   262  							{GUID: "fake-app-guid"},
   263  						},
   264  					}
   265  					routeRepo.FindReturns(route, nil)
   266  				})
   267  
   268  				It("tries to unbind the route from the app", func() {
   269  					Expect(err).NotTo(HaveOccurred())
   270  					Expect(routeRepo.UnbindCallCount()).To(Equal(1))
   271  					routeGUID, appGUID := routeRepo.UnbindArgsForCall(0)
   272  					Expect(routeGUID).To(Equal("route-guid"))
   273  					Expect(appGUID).To(Equal("fake-app-guid"))
   274  				})
   275  
   276  				Context("when unbinding the route from the app fails", func() {
   277  					BeforeEach(func() {
   278  						routeRepo.UnbindReturns(errors.New("unbind-err"))
   279  					})
   280  
   281  					It("returns an error", func() {
   282  						Expect(err).To(HaveOccurred())
   283  						Expect(err.Error()).To(Equal("unbind-err"))
   284  					})
   285  				})
   286  
   287  				Context("when unbinding the route from the app succeeds", func() {
   288  					BeforeEach(func() {
   289  						routeRepo.UnbindReturns(nil)
   290  					})
   291  
   292  					It("tells the user it succeeded", func() {
   293  						Expect(err).NotTo(HaveOccurred())
   294  						Expect(ui.Outputs()).To(BeInDisplayOrder(
   295  							[]string{"OK"},
   296  						))
   297  					})
   298  				})
   299  			})
   300  
   301  			Context("when the returned route does not have an app with the requested app's guid", func() {
   302  				BeforeEach(func() {
   303  					route := models.Route{
   304  						GUID: "route-guid",
   305  						Apps: []models.ApplicationFields{
   306  							{GUID: "other-fake-app-guid"},
   307  						},
   308  					}
   309  					routeRepo.FindReturns(route, nil)
   310  				})
   311  
   312  				It("does not unbind the route from the app", func() {
   313  					Expect(err).NotTo(HaveOccurred())
   314  					Expect(routeRepo.UnbindCallCount()).To(Equal(0))
   315  				})
   316  
   317  				It("tells the user 'OK'", func() {
   318  					Expect(err).NotTo(HaveOccurred())
   319  					Expect(ui.Outputs()).To(ContainSubstrings(
   320  						[]string{"OK"},
   321  					))
   322  				})
   323  
   324  				It("warns the user the route was not mapped to the application", func() {
   325  					Expect(err).NotTo(HaveOccurred())
   326  					Expect(ui.Outputs()).To(ContainSubstrings(
   327  						[]string{"Route to be unmapped is not currently mapped to the application."},
   328  					))
   329  				})
   330  			})
   331  		})
   332  
   333  		Context("when the route cannot be found", func() {
   334  			BeforeEach(func() {
   335  				routeRepo.FindReturns(models.Route{}, errors.New("find-by-host-and-domain-err"))
   336  			})
   337  
   338  			It("returns an error", func() {
   339  				Expect(err).To(HaveOccurred())
   340  				Expect(err.Error()).To(Equal("find-by-host-and-domain-err"))
   341  			})
   342  		})
   343  
   344  	})
   345  })