github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/romulus/agree/agree_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package agree_test
     5  
     6  import (
     7  	"runtime"
     8  	"sync"
     9  	"testing"
    10  
    11  	"github.com/juju/cmd/cmdtesting"
    12  	"github.com/juju/terms-client/api"
    13  	"github.com/juju/terms-client/api/wireformat"
    14  	jujutesting "github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/cmd/juju/romulus/agree"
    19  	coretesting "github.com/juju/juju/testing"
    20  )
    21  
    22  func TestPackage(t *testing.T) {
    23  	gc.TestingT(t)
    24  }
    25  
    26  var _ = gc.Suite(&agreeSuite{})
    27  
    28  var testTerms = "Test Terms"
    29  
    30  type agreeSuite struct {
    31  	client *mockClient
    32  	coretesting.FakeJujuXDGDataHomeSuite
    33  }
    34  
    35  func (s *agreeSuite) SetUpTest(c *gc.C) {
    36  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    37  	s.client = &mockClient{}
    38  
    39  	jujutesting.PatchValue(agree.ClientNew, func(...api.ClientOption) (api.Client, error) {
    40  		return s.client, nil
    41  	})
    42  }
    43  
    44  func (s *agreeSuite) TestAgreementNothingToSign(c *gc.C) {
    45  	jujutesting.PatchValue(agree.UserAnswer, func() (string, error) {
    46  		return "y", nil
    47  	})
    48  
    49  	s.client.user = "test-user"
    50  	s.client.setUnsignedTerms([]wireformat.GetTermsResponse{})
    51  
    52  	ctx, err := cmdtesting.RunCommand(c, agree.NewAgreeCommand(), "test-term/1")
    53  	c.Assert(err, jc.ErrorIsNil)
    54  	c.Assert(cmdtesting.Stdout(ctx), gc.Equals, `Already agreed
    55  `)
    56  }
    57  
    58  func (s *agreeSuite) TestAgreement(c *gc.C) {
    59  	if runtime.GOOS == "windows" {
    60  		c.Skip("less not on windows, bug 1614330")
    61  	}
    62  	var answer string
    63  	jujutesting.PatchValue(agree.UserAnswer, func() (string, error) {
    64  		return answer, nil
    65  	})
    66  
    67  	s.client.user = "test-user"
    68  	s.client.setUnsignedTerms([]wireformat.GetTermsResponse{{
    69  		Name:     "test-term",
    70  		Revision: 1,
    71  		Content:  testTerms,
    72  	}})
    73  	tests := []struct {
    74  		about       string
    75  		args        []string
    76  		err         string
    77  		stdout      string
    78  		answer      string
    79  		apiCalls    []jujutesting.StubCall
    80  		clientTerms []wireformat.GetTermsResponse
    81  	}{{
    82  		about:    "everything works",
    83  		args:     []string{"test-term/1", "--yes"},
    84  		stdout:   "Agreed to revision 1 of test-term for Juju users\n",
    85  		apiCalls: []jujutesting.StubCall{{FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermName: "test-term", TermRevision: 1}}}}}},
    86  	}, {
    87  		about:    "everything works with owner term",
    88  		args:     []string{"owner/test-term/1", "--yes"},
    89  		stdout:   "Agreed to revision 1 of owner/test-term for Juju users\n",
    90  		apiCalls: []jujutesting.StubCall{{FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermOwner: "owner", TermName: "test-term", TermRevision: 1}}}}}},
    91  	}, {
    92  		about: "cannot parse revision number",
    93  		args:  []string{"test-term/abc"},
    94  		err:   `must specify a valid term revision "test-term/abc"`,
    95  	}, {
    96  		about: "missing arguments",
    97  		args:  []string{},
    98  		err:   "missing arguments",
    99  	}, {
   100  		about:  "everything works - user accepts",
   101  		args:   []string{"test-term/1"},
   102  		answer: "y",
   103  		stdout: `
   104  === test-term/1: 0001-01-01 00:00:00 +0000 UTC ===
   105  Test Terms
   106  ========
   107  Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-term for Juju users
   108  `,
   109  		apiCalls: []jujutesting.StubCall{{
   110  			FuncName: "GetUnunsignedTerms", Args: []interface{}{
   111  				&wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1"}},
   112  			},
   113  		}, {
   114  			FuncName: "SaveAgreement", Args: []interface{}{
   115  				&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermName: "test-term", TermRevision: 1}}},
   116  			},
   117  		}},
   118  	}, {
   119  		about:  "everything works - user refuses",
   120  		args:   []string{"test-term/1"},
   121  		answer: "n",
   122  		stdout: `
   123  === test-term/1: 0001-01-01 00:00:00 +0000 UTC ===
   124  Test Terms
   125  ========
   126  Do you agree to the displayed terms? (Y/n): You didn't agree to the presented terms.
   127  `,
   128  		apiCalls: []jujutesting.StubCall{{
   129  			FuncName: "GetUnunsignedTerms", Args: []interface{}{
   130  				&wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1"}},
   131  			},
   132  		}},
   133  	}, {
   134  		about: "must not accept 0 revision",
   135  		args:  []string{"test-term/0", "--yes"},
   136  		err:   `must specify a valid term revision "test-term/0"`,
   137  	}, {
   138  		about:  "user accepts, multiple terms",
   139  		args:   []string{"test-term/1", "test-term/2"},
   140  		answer: "y",
   141  		stdout: `
   142  === test-term/1: 0001-01-01 00:00:00 +0000 UTC ===
   143  Test Terms
   144  ========
   145  Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-term for Juju users
   146  `,
   147  		apiCalls: []jujutesting.StubCall{
   148  			{
   149  				FuncName: "GetUnunsignedTerms", Args: []interface{}{
   150  					&wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1", "test-term/2"}},
   151  				},
   152  			}, {
   153  				FuncName: "SaveAgreement", Args: []interface{}{
   154  					&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{
   155  						{TermName: "test-term", TermRevision: 1},
   156  					}},
   157  				},
   158  			}},
   159  	}, {
   160  		about: "valid then unknown arguments",
   161  		args:  []string{"test-term/1", "unknown", "arguments"},
   162  		err:   `must specify a valid term revision "unknown"`,
   163  	}, {
   164  		about: "user accepts all the terms",
   165  		args:  []string{"test-term/1", "test-term/2", "--yes"},
   166  		stdout: `Agreed to revision 1 of test-term for Juju users
   167  Agreed to revision 2 of test-term for Juju users
   168  `,
   169  		apiCalls: []jujutesting.StubCall{
   170  			{FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{
   171  				Agreements: []wireformat.SaveAgreement{
   172  					{TermName: "test-term", TermRevision: 1},
   173  					{TermName: "test-term", TermRevision: 2},
   174  				}}}}},
   175  	}, {
   176  		about: "everything works with term owner - user accepts",
   177  		clientTerms: []wireformat.GetTermsResponse{{
   178  			Name:     "test-term",
   179  			Owner:    "test-owner",
   180  			Revision: 1,
   181  			Content:  testTerms,
   182  		}},
   183  		args:   []string{"test-owner/test-term/1"},
   184  		answer: "y",
   185  		stdout: `
   186  === test-owner/test-term/1: 0001-01-01 00:00:00 +0000 UTC ===
   187  Test Terms
   188  ========
   189  Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-owner/test-term for Juju users
   190  `,
   191  		apiCalls: []jujutesting.StubCall{{
   192  			FuncName: "GetUnunsignedTerms", Args: []interface{}{
   193  				&wireformat.CheckAgreementsRequest{Terms: []string{"test-owner/test-term/1"}},
   194  			},
   195  		}, {
   196  			FuncName: "SaveAgreement", Args: []interface{}{
   197  				&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermOwner: "test-owner", TermName: "test-term", TermRevision: 1}}},
   198  			},
   199  		}},
   200  	}}
   201  	for i, test := range tests {
   202  		s.client.ResetCalls()
   203  		if len(test.clientTerms) > 0 {
   204  			s.client.setUnsignedTerms(test.clientTerms)
   205  		}
   206  		c.Logf("running test %d: %s", i, test.about)
   207  		if test.answer != "" {
   208  			answer = test.answer
   209  		}
   210  		ctx, err := cmdtesting.RunCommand(c, agree.NewAgreeCommand(), test.args...)
   211  		if test.err != "" {
   212  			c.Assert(err, gc.ErrorMatches, test.err)
   213  		} else {
   214  			c.Assert(err, jc.ErrorIsNil)
   215  		}
   216  		if ctx != nil {
   217  			c.Assert(cmdtesting.Stdout(ctx), gc.Equals, test.stdout)
   218  		}
   219  		if len(test.apiCalls) > 0 {
   220  			s.client.CheckCalls(c, test.apiCalls)
   221  		}
   222  	}
   223  }
   224  
   225  type mockClient struct {
   226  	api.Client
   227  	jujutesting.Stub
   228  
   229  	lock          sync.Mutex
   230  	user          string
   231  	terms         []wireformat.GetTermsResponse
   232  	unsignedTerms []wireformat.GetTermsResponse
   233  }
   234  
   235  func (c *mockClient) setUnsignedTerms(t []wireformat.GetTermsResponse) {
   236  	c.lock.Lock()
   237  	defer c.lock.Unlock()
   238  	c.unsignedTerms = t
   239  }
   240  
   241  // SaveAgreement saves user's agreement to the specified
   242  // revision of the terms documents
   243  func (c *mockClient) SaveAgreement(p *wireformat.SaveAgreements) (*wireformat.SaveAgreementResponses, error) {
   244  	c.AddCall("SaveAgreement", p)
   245  	responses := make([]wireformat.AgreementResponse, len(p.Agreements))
   246  	for i, agreement := range p.Agreements {
   247  		responses[i] = wireformat.AgreementResponse{
   248  			User:     c.user,
   249  			Owner:    agreement.TermOwner,
   250  			Term:     agreement.TermName,
   251  			Revision: agreement.TermRevision,
   252  		}
   253  	}
   254  	return &wireformat.SaveAgreementResponses{responses}, nil
   255  }
   256  
   257  func (c *mockClient) GetUnsignedTerms(p *wireformat.CheckAgreementsRequest) ([]wireformat.GetTermsResponse, error) {
   258  	c.MethodCall(c, "GetUnunsignedTerms", p)
   259  	r := make([]wireformat.GetTermsResponse, len(c.unsignedTerms))
   260  	copy(r, c.unsignedTerms)
   261  	return r, nil
   262  }
   263  
   264  func (c *mockClient) GetUsersAgreements() ([]wireformat.AgreementResponse, error) {
   265  	c.MethodCall(c, "GetUsersAgreements")
   266  	return []wireformat.AgreementResponse{}, nil
   267  }