1+ import json
2+ import mock
3+
4+ import optimizely
5+
6+
7+ class APIResponseMock ():
8+ """ A class used to mock responses from the requests module
9+ """
10+ def __init__ (self , status_code = None , data = None , text = None ):
11+ self .status_code = status_code
12+ self .json = mock .Mock (return_value = data )
13+ self .text = text
14+
15+
16+ class APIMock ():
17+ """ A class used to mock the Optimizely API. Its get, post, put, and delete functions can be used to mock the
18+ requests module.
19+ """
20+ def __init__ (self , get_responses = None , post_responses = None , put_responses = None , delete_responses = None ,
21+ * args , ** kwargs ):
22+ self .get_responses = get_responses or {}
23+ self .post_responses = post_responses or {}
24+ self .put_responses = put_responses or {}
25+ self .delete_responses = delete_responses or {}
26+
27+ def get (self , url , ** kwargs ):
28+ return self .get_responses [url ]
29+
30+ def post (self , url , ** kwargs ):
31+ return self .post_responses [url ]
32+
33+ def put (self , url , ** kwargs ):
34+ return self .put_responses [url ]
35+
36+ def delete (self , url , ** kwargs ):
37+ return self .delete_responses [url ]
38+
39+
40+ class TestResource (object ):
41+ """ Base class used for testing Optimizely API Resources. It includes the base tests for standard/shared API
42+ requests
43+ """
44+
45+ def create_mocks (self ):
46+ # create updated data mocks
47+ self .sample_data_updated = self .sample_data .copy ()
48+ self .sample_data_updated .update (self .sample_updates )
49+
50+ # mock requests module
51+ self .mock_api_get = APIResponseMock (200 , self .sample_data )
52+ self .mock_api_create = APIResponseMock (201 , self .sample_data )
53+ self .mock_api_list = APIResponseMock (200 , [self .sample_data , self .sample_data ])
54+ self .mock_api_update = APIResponseMock (200 , self .sample_data_updated )
55+ self .mock_api_delete = APIResponseMock (204 , None )
56+ self .mock_api = APIMock (get_responses = {
57+ optimizely .api_base + self .test_resource .endpoint + str (self .id ): self .mock_api_get ,
58+ optimizely .api_base + self .test_resource .endpoint : self .mock_api_list
59+ }, post_responses = {
60+ optimizely .api_base + self .test_resource .endpoint : self .mock_api_create
61+ }, put_responses = {
62+ optimizely .api_base + self .test_resource .endpoint + str (self .id ): self .mock_api_update
63+ }, delete_responses = {
64+ optimizely .api_base + self .test_resource .endpoint + str (self .id ): self .mock_api_delete
65+ })
66+ requests_mock = mock .Mock ()
67+ requests_mock .get = mock .Mock (side_effect = self .mock_api .get )
68+ requests_mock .post = mock .Mock (side_effect = self .mock_api .post )
69+ requests_mock .put = mock .Mock (side_effect = self .mock_api .put )
70+ requests_mock .delete = mock .Mock (side_effect = self .mock_api .delete )
71+ self .p = mock .patch ('optimizely.requests' , new = requests_mock )
72+ self .p .start ()
73+
74+ def tearDown (self ):
75+ # if optimizely.requests has been patched, unpatch at the end of each test
76+ if hasattr (self , 'p' ):
77+ self .p .stop ()
78+
79+ def test_list (self ):
80+ """ Tests that .list() successfully retrieves two objects
81+ """
82+ # call .list()
83+ resources = self .test_resource .list ()
84+
85+ # ensure that the correct GET request was made
86+ optimizely .requests .get .assert_called_with (optimizely .api_base + self .test_resource .endpoint ,
87+ headers = {'Token' : optimizely .api_key })
88+
89+ # ensure that values and types are correct
90+ self .assertEqual (2 , len (resources ))
91+ for resource in resources :
92+ for k , v in self .sample_data .iteritems ():
93+ self .assertEquals (v , resource .__getattribute__ (k ))
94+ self .assertIsInstance (resource , self .test_resource )
95+
96+ def test_get (self ):
97+ """ Tests that .get() successfully retrieves the correct object
98+ """
99+ # call .get()
100+ resource = self .test_resource .get (self .id )
101+
102+ # ensure that the correct GET request was made
103+ optimizely .requests .get .assert_called_with (optimizely .api_base + self .test_resource .endpoint +
104+ str (self .id ), headers = {'Token' : optimizely .api_key })
105+
106+ # ensure that values and type are correct
107+ for k , v in self .sample_data .iteritems ():
108+ self .assertEquals (v , resource .__getattribute__ (k ))
109+ self .assertIsInstance (resource , self .test_resource )
110+
111+ def test_create (self ):
112+ """ Tests that .create() successfully creates and retrieves the correct object
113+ """
114+ # call .create()
115+ resource = self .test_resource .create (self .sample_data )
116+
117+ # ensure that the correct POST request was made
118+ optimizely .requests .post .assert_called_with (optimizely .api_base + self .test_resource .endpoint ,
119+ data = json .dumps (self .sample_data ),
120+ headers = {'Token' : optimizely .api_key ,
121+ 'Content-Type' : 'application/json' })
122+
123+ # ensure that values and type are correct
124+ for k , v in self .sample_data .iteritems ():
125+ self .assertEquals (v , resource .__getattribute__ (k ))
126+ self .assertIsInstance (resource , self .test_resource )
127+
128+ def test_update (self ):
129+ """ Tests that .update() successfully creates and retrieves the correct object
130+ """
131+ # call .create()
132+ resource = self .test_resource .update (self .id , self .sample_updates )
133+
134+ # ensure that the correct PUT request was made
135+ optimizely .requests .put .assert_called_with (optimizely .api_base + self .test_resource .endpoint + str (self .id ),
136+ data = json .dumps (self .sample_updates ),
137+ headers = {'Token' : optimizely .api_key ,
138+ 'Content-Type' : 'application/json' })
139+
140+ # ensure that values and type are correct
141+ for k , v in self .sample_data_updated .iteritems ():
142+ self .assertEquals (v , resource .__getattribute__ (k ))
143+ self .assertIsInstance (resource , self .test_resource )
144+
145+ def test_delete (self ):
146+ """ Tests that .delete() calls the correct endpoint and that it returns None upon success
147+ """
148+ # call .delete()
149+ return_value = self .test_resource .delete (self .id )
150+
151+ # ensure that the correct DELETE request was made
152+ optimizely .requests .delete .assert_called_with (optimizely .api_base + self .test_resource .endpoint +
153+ str (self .id ), headers = {'Token' : optimizely .api_key })
154+
155+ # ensure that None is returned
156+ self .assertIsNone (return_value )
0 commit comments