def set_colorspec(client): color_specs = client.get("config/color_specs")['body'].decode('UTF-8') response = Menu.prompt("Enter colorspec {}: ".format(color_specs)) if response not in color_specs: print("Mode must be one of {}".format(color_specs)) else: client.post("lamp?color_name={}".format(response))
def set_colorspec(client) : color_specs = client.get("config/color_specs")['body'].decode('UTF-8') response = Menu.prompt("Enter colorspec {}: ".format(color_specs)) if response not in color_specs : print("Mode must be one of {}".format(color_specs)) else : client.post("lamp?color_name={}".format(response))
def test_login_bad_password(client): response, new_user = register_user(client) assert http.client.OK == response.status_code username = new_user['username'] response = activate_user(client, new_user['username']) assert http.client.OK == response.status_code user_id = fake.pyint() headers = get_headers(username, user_id) response = client.post('/api/auth/logout/', headers=headers) result = response.json assert http.client.OK == response.status_code expected = { 'Authorized': None, } assert result == expected user_data = get_login_user_from_register_user(new_user) user_data['password'] = '' response = client.post('/api/auth/login/', data=user_data) assert http.client.UNAUTHORIZED == response.status_code response = delete_user(client, new_user) assert http.client.NO_CONTENT == response.status_code
def reset(client): response = Menu.prompt( "Are you sure you want to reset? (Any changes will be lost) [y|n]: " ) if response not in ['y', 'n']: print("Answer must be one of [y|n]") elif response is 'y': client.post("reset")
def test_schedule(client) : print("Testing schedule ...") colors = get_colors(client) schedule = create_schedule(colors) try : print("Setting wake_and_bake schedule to {} ...".format(schedule)) client.post('schedule?name=wake_and_bake', headers={'content-type': 'application/json'}, body=json.dumps(schedule).encode('UTF-8')) set_mode(client, "scheduler") sleep_ms(60*1000) finally : set_mode(client, "off")
def test_comment_on_patch(self): with open(filepath('test-patch-adds-items.json')) as f: patch = f.read() with self.client as client: res = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_id = int(res.headers['Location'].split('/')[-2]) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'messages', data=json.dumps({'message': 'This is a comment'}), content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'} ) self.assertEqual(res.status_code, http.client.OK) self.assertEqual(patch_url, urlparse(res.headers['Location']).path) row = database.query_db( 'SELECT * FROM patch_request_comment WHERE patch_request_id=?', (patch_id,), one=True) self.assertEqual('https://orcid.org/1234-5678-9101-112X', row['author']) self.assertEqual(patch_id, row['patch_request_id']) self.assertEqual('This is a comment', row['message']) res = client.get(patch_url) comments = json.loads(res.get_data(as_text=True)).get('comments') self.assertEqual(1, len(comments))
def test_list_thoughts_search(client, thought_fixture): username = fake.name() new_thought = {'username': username, 'text': 'A tale about a Platypus'} header = token_validation.generate_token_header(username, PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/thoughts/', data=new_thought, headers=headers) assert http.client.CREATED == response.status_code response = client.get('/api/thoughts/?search=platypus') result = response.json assert http.client.OK == response.status_code assert len(result) > 0 # Check that the returned values contain "platypus" for thought in result: expected = { 'text': ANY, 'username': username, 'id': ANY, 'timestamp': ANY, } assert expected == thought assert 'platypus' in thought['text'].lower()
def tweet_fixture(client): ''' Generate three tweets in the system. ''' tweet_ids = [] for _ in range(3): tweet = { 'text': fake.text(240), } header = token_validation.generate_token_header( fake.name(), PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/tweets/', data=tweet, headers=headers) assert http.client.CREATED == response.status_code result = response.json tweet_ids.append(result['id']) yield tweet_ids # Clean up all tweets response = client.get('/api/tweets/') tweets = response.json for tweet in tweets: tweet_id = tweet['id'] url = f'/admin/tweets/{tweet_id}/' response = client.delete(url) assert http.client.NO_CONTENT == response.status_code
def test_create_me_article(client): new_article = { 'slug': fake.slug(), 'title': fake.text(250), 'content': fake.text(500), 'category_id': fake.random_int(1, 3), 'status': 'DRAFT' } user_payload = { 'userid': fake.random_int(2, 100), 'username': fake.user_name(), 'email': fake.email() } header = token_validation.generate_token_header(user_payload, PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/articles', data=new_article, headers=headers) result = response.json assert http.client.CREATED == response.status_code expected = { 'id': ANY, 'slug': new_article['slug'], 'title': new_article['title'], 'content': new_article['content'], 'author_id': ANY, 'category_id': new_article['category_id'], 'status': new_article['status'], 'published': ANY } assert result == expected
def test_create_me_area(client): new_area = { 'username': fake.name(), 'areacode': fake.text(240), 'area': fake.text(240), 'zonecode': fake.text(240), } header = token_validation.generate_token_header(fake.name(), PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/areas/', data=new_area, headers=headers) result = response.json assert http.client.CREATED == response.status_code expected = { 'id': ANY, 'username': ANY, 'areacode': new_area['areacode'], 'area': new_area['area'], 'zonecode': new_area['zonecode'], 'timestamp': '2019-05-07T13:47:34', } assert result == expected
def area_fixture(client): ''' Generate three areas in the system. ''' area_ids = [] for _ in range(3): area = { 'areacode': fake.text(240), 'area': fake.text(240), 'zonecode': fake.text(240), } header = token_validation.generate_token_header( fake.name(), PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/areas/', data=area, headers=headers) assert http.client.CREATED == response.status_code result = response.json area_ids.append(result['id']) yield area_ids # Clean up all areas response = client.get('/api/areas/') areas = response.json for area in areas: area_id = area['id'] url = f'/admin/areas/{area_id}/' response = client.delete(url) assert http.client.NO_CONTENT == response.status_code
def offer_fixture(client): ''' Generate three offers in the system. ''' offer_ids = [] for _ in range(3): offer = { 'title': fake.text(150), 'description': fake.text(250), 'category': fake.text(20), 'latitude': fake.latitude(), 'longitude': fake.longitude(), 'picture_url': fake.text(150), } header = token_validation.generate_token_header( fake.name(), PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/offers/', data=offer, headers=headers) assert http.client.CREATED == response.status_code result = response.json offer_ids.append(result['id']) yield offer_ids # Clean up all offers response = client.get('/api/offers/') offers = response.json for offer in offers: offer_id = offer['id'] url = f'/admin/offers/{offer_id}/' response = client.delete(url) assert http.client.NO_CONTENT == response.status_code
def test_history_turtle(self): with self.client as client: res = client.patch( '/d/', data=self.patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) res = client.post( urlparse(res.headers['Location']).path + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) res1 = self.client.get('/history.ttl') self.assertEqual(res1.status_code, http.client.OK) self.assertEqual(res1.headers['Content-Type'], 'text/turtle') self.assertEqual( res1.headers['Cache-Control'], 'public, max-age={}'.format(cache.SHORT_TIME)) self.assertEqual( res1.headers['Content-Disposition'], 'attachment; filename="periodo-history.ttl"') g = Graph() g.parse(data=res1.get_data(as_text=True), format='turtle') self.assertIn((HOST['h#patch-1'], FOAF.page, HOST['patches/1/patch.jsonpatch']), g) self.assertIn((HOST['d'], DCTERMS.provenance, HOST['h#changes']), g) res3 = self.client.get('/history.ttl/') self.assertEqual(res3.status_code, http.client.NOT_FOUND)
def post_updated_nodes(client, rack_id, tag_name, tag_definition, added, removed): """Update the nodes relevant for a particular tag. :param client: MAAS client :param rack_id: System ID for rack controller :param tag_name: Name of tag :param tag_definition: Definition of the tag, used to assure that the work being done matches the current value. :param added: Set of nodes to add :param removed: Set of nodes to remove """ path = '/api/2.0/tags/%s/' % (tag_name, ) maaslog.debug("Updating nodes for %s, adding %s removing %s" % (tag_name, len(added), len(removed))) try: return process_response( client.post(path, op='update_nodes', as_json=True, rack_controller=rack_id, definition=tag_definition, add=added, remove=removed)) except urllib.error.HTTPError as e: if e.code == http.client.CONFLICT: if e.fp is not None: msg = e.fp.read() else: msg = e.msg maaslog.info("Got a CONFLICT while updating tag: %s", msg) return {} raise
def test_list_tweets_search(client, tweet_fixture): username = fake.name() new_tweet = { 'username': username, 'text': 'Do you dream about the City at the End of Time?' } header = token_validation.generate_token_header(username, PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/tweets/', data=new_tweet, headers=headers) assert http.client.CREATED == response.status_code response = client.get('/api/tweets/?search=City') result = response.json assert http.client.OK == response.status_code assert len(result) > 0 # Check that the returned values contain "city" for tweet in result: expected = { 'text': ANY, 'username': ANY, # can be other users who put messages 'id': ANY, 'timestamp': ANY, } assert expected == tweet print(tweet) assert 'city' in tweet['text'].lower()
def test_create_me_offer(client): new_offer = { 'username': fake.name(), 'title': fake.text(150), 'description': fake.text(240), 'category': fake.text(50), 'latitude': fake.latitude(), 'longitude': fake.longitude(), 'picture_url': fake.text(150), } header = token_validation.generate_token_header(fake.name(), PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/offers/', data=new_offer, headers=headers) result = response.json assert http.client.CREATED == response.status_code expected = { 'id': ANY, 'username': ANY, 'title': new_offer['title'], 'description': new_offer['description'], 'category': new_offer['category'], 'latitude': ANY, 'longitude': ANY, 'picture_url': new_offer['picture_url'], 'timestamp': '2019-05-07T13:47:34', } assert result == expected
def article_fixture(client): ''' Generate five articles in the system. ''' article_ids = [] user_payload = { 'userid': 1, 'username': '******', 'email': '*****@*****.**' } for _ in range(5): article = { 'slug': fake.slug(), 'title': fake.text(250), 'content': fake.text(500), 'category_id': fake.random_int(1, 3), 'status': 'DRAFT' } header = token_validation.generate_token_header( user_payload, PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/articles', data=article, headers=headers) assert http.client.CREATED == response.status_code result = response.json article_ids.append(result['id']) yield article_ids
def test_create_me_unauthorized(client): new_thought = { 'username': fake.name(), 'text': fake.text(240), } response = client.post('/api/me/thoughts/', data=new_thought) assert http.client.UNAUTHORIZED == response.status_code
def test_list_me_thoughts(client, thought_fixture): username = fake.name() text = fake.text(240) # Create a new thought new_thought = { 'text': text, } header = token_validation.generate_token_header(username, PRIVATE_KEY) headers = { 'Authorization': header, } response = client.post('/api/me/thoughts/', data=new_thought, headers=headers) result = response.json assert http.client.CREATED == response.status_code # Get the thoughts of the user response = client.get('/api/me/thoughts/', headers=headers) results = response.json assert http.client.OK == response.status_code assert len(results) == 1 result = results[0] expected_result = { 'id': ANY, 'username': username, 'text': text, 'timestamp': ANY, } assert result == expected_result
def test_POST_update_nodes_allows_rack_controller(self): tag = factory.make_Tag() rack_controller = factory.make_RackController() node = factory.make_Node() client = make_worker_client(rack_controller) tokens = list(get_auth_tokens(rack_controller.owner)) if len(tokens) > 0: # Use the latest token. token = tokens[-1] else: token = create_auth_token(rack_controller.owner) token.save() creds = convert_tuple_to_string(get_creds_tuple(token)) response = client.post( self.get_tag_uri(tag), { 'op': 'update_nodes', 'add': [node.system_id], 'rack_controller': rack_controller.system_id, 'credentials': creds, }) self.assertEqual(http.client.OK, response.status_code) parsed_result = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) self.assertEqual({'added': 1, 'removed': 0}, parsed_result) self.assertItemsEqual([node], tag.node_set.all())
def test_update_merged_patch(self): with self.client as client: res = client.patch( '/d/', data=self.patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_path = urlparse(res.headers['Location']).path res = client.post( patch_path + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) res = client.put( patch_path + 'patch.jsonpatch', data=self.patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) self.assertEqual(res.status_code, http.client.FORBIDDEN) self.assertEqual( res.headers['WWW-Authenticate'], 'Bearer realm="PeriodO", error="insufficient_scope", ' + 'error_description=' + '"The access token does not provide sufficient privileges", ' + 'error_uri="http://tools.ietf.org/html/rfc6750#section-6.2.3"')
def test_admin_merge(self): with self.client as client: res = client.patch( '/d/', data=self.patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_id = int(res.headers['Location'].split('/')[-2]) # Test that there's a link header patch_url = urlparse(res.headers['Location']).path res = self.client.get(patch_url, headers={ 'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.headers.get('Link'), '<{}>;rel="merge"'.format(patch_url + 'merge')) res = client.post( patch_url + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) merger = database.query_db( 'SELECT merged_by FROM patch_request WHERE id = ?', (patch_id,), one=True)['merged_by'] self.assertEqual(merger, 'http://orcid.org/1211-1098-7654-321X')
def test_remove_period(self): with open(filepath('test-patch-remove-period.json')) as f: patch1 = f.read() with self.client as client: res = client.patch( '/d/', data=patch1, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) removed_entities = database.get_removed_entity_keys() self.assertEqual(removed_entities, set(['p0trgkvwbjd'])) res = client.get('/trgkvwbjd', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.GONE) res = client.get('/trgkvwbjd.json', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.GONE) res = client.get('/trgkvwbjd?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('/trgkvwbjd.json?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('/trgkvwbjd?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) res = client.get('/trgkvwbjd.json?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) res = client.get('/history.jsonld?inline-context') self.assertEqual( res.headers['Cache-Control'], 'public, max-age=0') self.assertEqual( res.headers['X-Accel-Expires'], '{}'.format(cache.MEDIUM_TIME)) g = ConjunctiveGraph() g.parse(format='json-ld', data=res.get_data(as_text=True)) generated = list(g.objects(subject=HOST['h#change-2'], predicate=PROV.generated)) self.assertEqual(len(generated), 1) self.assertIn(HOST['d?version=2'], generated)
def test_post_numbers_non_numbers(client): """ Verify the app returns a 422 for lists containing non numbers. """ request_data = {'numbers': ['a', '1', '2']} response = client.post(path, data=request_data) assert response.status_code == http.client.UNPROCESSABLE_ENTITY
def test_remove_definition(self): with open(filepath('test-patch-remove-definition.json')) as f: patch1 = f.read() with self.client as client: res = client.patch( '/d/', data=patch1, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) removed_entities = database.get_removed_entity_keys() self.assertEqual(removed_entities, set(['p0trgkvwbjd'])) res = client.get('/trgkvwbjd', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.GONE) res = client.get('/trgkvwbjd.json', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.GONE) res = client.get('/trgkvwbjd?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('/trgkvwbjd.json?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('/trgkvwbjd?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) res = client.get('/trgkvwbjd.json?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) res = client.get('/h') g = ConjunctiveGraph() g.parse(format='json-ld', data=res.get_data(as_text=True)) invalidated = g.value(subject=PERIODO['p0h#change-2'], predicate=PROV.invalidated, any=False) self.assertEqual(invalidated, PERIODO['p0trgkvwbjd']) generated = list(g.objects(subject=PERIODO['p0h#change-2'], predicate=PROV.generated)) self.assertEqual(len(generated), 2) self.assertIn(PERIODO['p0d?version=2'], generated) self.assertIn(PERIODO['p0trgkv?version=2'], generated)
def test_post_update_view(): response = client.post(reverse('prod_edit', args='7'), { 'title': 'Updated title', 'info': 'Updated text', 'price': 101, }) for post in Post.objects.all(): print(f"---{post.pk}---") assert response.status_code == 302
def test_login(client): USERNAME = fake.name() PASSWORD = fake.password(length=15, special_chars=True) new_user = { 'username': USERNAME, 'password': PASSWORD, } response = client.post('/admin/users/', data=new_user) assert http.client.CREATED == response.status_code response = client.post('/api/login/', data=new_user) result = response.json assert http.client.OK == response.status_code expected = { 'Authorized': ANY, } assert result == expected
def test_post_non_string(client): """ Verify the app returns a 422 if an element is not a string. """ request_data = { 'strings': ['1', 2.5, '3'] } response = client.post(path, json=request_data) assert response.status_code == http.client.UNPROCESSABLE_ENTITY
def test_create_me_unauthorized(client): new_area = { 'username': fake.name(), 'areacode': fake.text(240), 'area': fake.text(240), 'zonecode': fake.text(240), } response = client.post('/api/me/areas/', data=new_area) assert http.client.UNAUTHORIZED == response.status_code
def post_json(client, data=None, file=None): if file: file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', file) with open(file_path, 'r') as file: data = file.read() return client.post('/calculate', data=data, content_type='application/json')
def test_post_numbers_numbers(client): """ Verify the app returns a sorted list for numbers. """ request_data = {'numbers': [1, 5, 4, 2, 3]} expected = [1, 2, 3, 4, 5] response = client.post(path, json=request_data) assert response.status_code == http.client.OK response_data = json.loads(response.data) assert response_data == expected
def test_create_me_articles_unauthorized(client): new_article = { 'slug': fake.slug(), 'title': fake.text(250), 'content': fake.text(500), 'category_id': fake.random_int(1, 3), 'status': 'DRAFT' } response = client.post('/api/me/articles', data=new_article) assert http.client.UNAUTHORIZED == response.status_code
def test_post_create_view(): response = client.post(reverse('prod_new'), { 'title': 'New title', 'info': 'New text', 'author': user, 'price': 100, }) assert response.status_code == 200 assert 'New title' in response assert 'New text' in response assert 100 in response
def test_create_product(client, product_fixture): new_product = { 'product_description': 'New product', } response = client.post('/api/product/', data=new_product) result = response.json assert http.client.CREATED == response.status_code expected = {'product_id': ANY, 'product_description': 'New product'} assert result == expected
def test_POST_update_nodes_refuses_unidentified_rack_controller(self): tag = factory.make_Tag() rack_controller = factory.make_RackController() node = factory.make_Node() client = make_worker_client(rack_controller) # We don't pass rack controller system_id so we get refused. response = client.post( self.get_tag_uri(tag), {"op": "update_nodes", "add": [node.system_id]}, ) self.assertEqual(http.client.FORBIDDEN, response.status_code) self.assertItemsEqual([], tag.node_set.all())
def test_create_me_unauthorized(client): new_offer = { 'username': fake.name(), 'title': fake.text(150), 'description': fake.text(240), 'category': fake.text(50), 'latitude': fake.latitude(), 'longitude': fake.longitude(), 'picture_url': fake.text(150), } response = client.post('/api/me/offers/', data=new_offer) assert http.client.UNAUTHORIZED == response.status_code
def test_invalid_oauth_request(self): # An OAuth-signed request that does not validate is an error. user = factory.make_User() client = MAASSensibleOAuthClient(user) # Delete the user's API keys. get_auth_tokens(user).delete() response = client.post(reverse('nodes_handler'), {'op': 'start'}) observed = response.status_code, response.content expected = ( Equals(http.client.UNAUTHORIZED), Contains(b"Invalid access token:"), ) self.assertThat(observed, MatchesListwise(expected))
def test_merge_patch(self): with open(filepath('test-patch-adds-items.json')) as f: patch = f.read() with self.client as client: res = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_id = int(res.headers['Location'].split('/')[-2]) updated_entities = database.query_db( 'SELECT updated_entities FROM patch_request WHERE id = ?', (patch_id,), one=True)['updated_entities'] self.assertEqual(updated_entities, '["p0trgkv"]') created_entities = database.query_db( 'SELECT created_entities FROM patch_request WHERE id = ?', (patch_id,), one=True)['created_entities'] self.assertEqual(created_entities, '[]') patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) row = database.query_db( 'SELECT applied_to, resulted_in FROM patch_request WHERE id=?', (patch_id,), one=True) self.assertEqual(1, row['applied_to']) self.assertEqual(2, row['resulted_in']) updated_entities = database.query_db( 'SELECT updated_entities FROM patch_request WHERE id = ?', (patch_id,), one=True)['updated_entities'] self.assertEqual(updated_entities, '["p0trgkv"]') created_entities = json.loads(database.query_db( 'SELECT created_entities FROM patch_request WHERE id = ?', (patch_id,), one=True)['created_entities']) self.assertEqual(4, len(created_entities)) for entity_id in created_entities: self.assertRegex(entity_id, identifier.IDENTIFIER_RE)
def test_reject_patch(self): with open(filepath('test-patch-adds-items.json')) as f: patch = f.read() with self.client as client: res = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_id = int(res.headers['Location'].split('/')[-2]) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'reject', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) row = database.query_db( 'SELECT open, merged FROM patch_request WHERE id=?', (patch_id,), one=True) self.assertEqual(0, row['open']) self.assertEqual(0, row['merged'])
def test_add_contributors_to_dataset_description(self): contribution = (URIRef('http://n2t.net/ark:/99152/p0d'), DCTERMS.contributor, URIRef('http://orcid.org/1234-5678-9101-112X')) data = self.client.get( '/', headers={'Accept': 'text/turtle'}).get_data(as_text=True) g = Graph().parse(format='turtle', data=data) self.assertNotIn(contribution, g) with self.client as client: res = client.patch( '/d/', data=self.patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) res = client.post( urlparse(res.headers['Location']).path + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) data = self.client.get( '/', headers={'Accept': 'text/turtle'}).get_data(as_text=True) g = Graph().parse(format='turtle', data=data) self.assertIn(contribution, g)
def reboot(client) : client.post("reboot")
def test_get_history(self): with open(filepath('test-patch-adds-items.json')) as f: patch = f.read() with self.client as client: res1 = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res1.headers['Location']).path client.post( patch_url + 'messages', data='{"message": "Here is my patch"}', content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) client.post( patch_url + 'messages', data='{"message": "Looks good to me"}', content_type='application/json', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) res3 = client.get('/h', headers={'Accept': 'application/ld+json'}) self.assertEqual(res3.status_code, http.client.SEE_OTHER) self.assertEqual( urlparse(res3.headers['Location']).path, '/h.jsonld') res4 = client.get('/history.jsonld?inline-context') self.assertEqual(res4.status_code, http.client.OK) self.assertEqual( res4.headers['Content-Type'], 'application/ld+json') jsonld = res4.get_data(as_text=True) g = ConjunctiveGraph() g.parse(format='json-ld', data=jsonld) # Initial data load self.assertIn( # None means any (HOST['h#change-1'], PROV.endedAtTime, None), g) self.assertIn( (HOST['h#change-1'], PROV.used, HOST['d?version=0']), g) self.assertIn( (HOST['d?version=0'], PROV.specializationOf, HOST['d']), g) self.assertIn( (HOST['h#change-1'], RDFS.seeAlso, HOST['h#patch-request-1']), g) self.assertIn( (HOST['h#patch-request-1'], FOAF.page, HOST['patches/1/']), g) self.assertNotIn( (HOST['h#patch-request-1'], AS.replies, HOST['h#patch-request-1-comments']), g) self.assertIn( (HOST['h#change-1'], PROV.used, HOST['h#patch-1']), g) self.assertIn( (HOST['h#patch-1'], FOAF.page, HOST['patches/1/patch.jsonpatch']), g) self.assertIn( (HOST['h#change-1'], PROV.generated, HOST['d?version=1']), g) self.assertIn( (HOST['d?version=1'], PROV.specializationOf, HOST['d']), g) # Change from first submitted patch self.assertIn( # None means any (HOST['h#change-2'], PROV.startedAtTime, None), g) self.assertIn( # None means any (HOST['h#change-2'], PROV.endedAtTime, None), g) start = g.value( subject=HOST['h#change-2'], predicate=PROV.startedAtTime) self.assertEqual(start.datatype, XSD.dateTime) self.assertRegex(start.value.isoformat(), W3CDTF) end = g.value( subject=HOST['h#change-2'], predicate=PROV.endedAtTime) self.assertEqual(end.datatype, XSD.dateTime) self.assertRegex(end.value.isoformat(), W3CDTF) self.assertIn( (HOST['h#change-2'], PROV.wasAssociatedWith, URIRef('https://orcid.org/1234-5678-9101-112X')), g) self.assertIn( (HOST['h#change-2'], PROV.wasAssociatedWith, URIRef('https://orcid.org/1211-1098-7654-321X')), g) for association in g.subjects( predicate=PROV.agent, object=URIRef('https://orcid.org/1234-5678-9101-112X')): role = g.value(subject=association, predicate=PROV.hadRole) self.assertIn(role, (HOST['v#submitted'], HOST['v#updated'])) merger = g.value( predicate=PROV.agent, object=URIRef('https://orcid.org/1211-1098-7654-321X')) self.assertIn( (HOST['h#change-2'], PROV.qualifiedAssociation, merger), g) self.assertIn( (merger, PROV.hadRole, HOST['v#merged']), g) self.assertIn( (HOST['h#change-2'], PROV.used, HOST['d?version=1']), g) self.assertIn( (HOST['d?version=1'], PROV.specializationOf, HOST['d']), g) self.assertIn( (HOST['h#change-2'], RDFS.seeAlso, HOST['h#patch-request-2']), g) self.assertIn( (HOST['h#patch-request-2'], FOAF.page, HOST['patches/2/']), g) self.assertIn( (HOST['h#patch-request-2'], AS.replies, HOST['h#patch-request-2-comments']), g) commentCount = g.value( subject=HOST['h#patch-request-2-comments'], predicate=AS.totalItems) self.assertEqual(commentCount.value, 2) self.assertIn( (HOST['h#patch-request-2-comments'], AS.first, HOST['h#patch-request-2-comment-1']), g) self.assertIn( (HOST['h#patch-request-2-comments'], AS.last, HOST['h#patch-request-2-comment-2']), g) self.assertIn( (HOST['h#patch-request-2-comments'], AS.items, HOST['h#patch-request-2-comment-1']), g) self.assertIn( (HOST['h#patch-request-2-comments'], AS.items, HOST['h#patch-request-2-comment-2']), g) self.assertIn( (HOST['h#patch-request-2-comment-1'], RDF.type, AS.Note), g) self.assertIn( (HOST['h#patch-request-2-comment-1'], AS.attributedTo, URIRef('https://orcid.org/1234-5678-9101-112X')), g) self.assertIn( # None means any (HOST['h#patch-request-2-comment-1'], AS.published, None), g) comment1_media_type = g.value( subject=HOST['h#patch-request-2-comment-1'], predicate=AS.mediaType) self.assertEqual(comment1_media_type.value, 'text/plain') comment1_content = g.value( subject=HOST['h#patch-request-2-comment-1'], predicate=AS.content) self.assertEqual(comment1_content.value, 'Here is my patch') self.assertIn( (HOST['h#patch-request-2-comment-2'], RDF.type, AS.Note), g) self.assertIn( (HOST['h#patch-request-2-comment-2'], AS.attributedTo, URIRef('https://orcid.org/1211-1098-7654-321X')), g) self.assertIn( # None means any (HOST['h#patch-request-2-comment-2'], AS.published, None), g) comment2_media_type = g.value( subject=HOST['h#patch-request-2-comment-2'], predicate=AS.mediaType) self.assertEqual(comment2_media_type.value, 'text/plain') comment2_content = g.value( subject=HOST['h#patch-request-2-comment-2'], predicate=AS.content) self.assertEqual(comment2_content.value, 'Looks good to me') self.assertIn( (HOST['h#change-2'], PROV.used, HOST['h#patch-2']), g) self.assertIn( (HOST['h#patch-2'], FOAF.page, HOST['patches/2/patch.jsonpatch']), g) self.assertIn( (HOST['h#change-2'], PROV.generated, HOST['d?version=2']), g) self.assertIn( (HOST['d?version=2'], PROV.specializationOf, HOST['d']), g)
def set_pin(client) : response = Menu.prompt("Enter pin: ") client.post("np?pin={}".format(int(response)))
def test_versioning(self): with open(filepath('test-patch-adds-items.json')) as f: patch1 = f.read() with open(filepath('test-patch-add-definition.json')) as f: patch2 = f.read() with self.client as client: res = client.patch( '/d/', data=patch1, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) res = client.patch( '/d/', data=patch2, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) res = client.get('/trgkv?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) for version in range(1, 4): res = client.get( '/trgkv?version={}'.format(version), headers={'Accept': 'application/json'}) self.assertEqual( res.status_code, http.client.SEE_OTHER) self.assertEqual( '/' + res.headers['Location'].split('/')[-1], '/trgkv.json?version={}'.format(version)) res = client.get( '/trgkv.json?version={}'.format(version)) self.assertEqual( res.status_code, http.client.OK) self.assertEqual( res.headers['Content-Type'], 'application/json') res = client.get('/h') g = ConjunctiveGraph() g.parse(format='json-ld', data=res.get_data(as_text=True)) for o in g.objects(subject=PERIODO['p0h#change-3'], predicate=PROV.generated): path = '/' + urlparse(o).path.split('/')[-1][2:] if path == '/trgkv' or path == '/d': continue for version in range(0, 3): res = client.get( '{}?version={}'.format(path, version), headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('{}?version=3'.format(path), headers={'Accept': 'application/json'}) self.assertEqual(res.status_code, http.client.SEE_OTHER) self.assertEqual( '/' + res.headers['Location'].split('/')[-1], '{}.json?version=3'.format(path)) res = client.get( '{}.json?version=3'.format(path)) self.assertEqual( res.status_code, http.client.OK) self.assertEqual( res.headers['Content-Type'], 'application/json') for o in g.objects(subject=PERIODO['p0h#change-2'], predicate=PROV.generated): path = '/' + urlparse(o).path.split('/')[-1][2:] if path == '/trgkv' or path == '/d': continue for version in range(0, 2): res = client.get( '{}?version={}'.format(path, version), headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('{}?version=3'.format(path), headers={'Accept': 'application/json'}) self.assertEqual(res.status_code, http.client.SEE_OTHER) self.assertEqual( '/' + res.headers['Location'].split('/')[-1], '{}.json?version=3'.format(path)) res = client.get('{}.json?version=3'.format(path)) self.assertEqual( res.status_code, http.client.MOVED_PERMANENTLY) self.assertEqual( '/' + res.headers['Location'].split('/')[-1], '{}.json?version=2'.format(path)) res = client.get( '{}.json?version=2'.format(path)) self.assertEqual( res.status_code, http.client.OK) self.assertEqual( res.headers['Content-Type'], 'application/json')
def set_num_pixels(client) : response = Menu.prompt("Enter num_pixels: ") client.post("np?num_pixels={}".format(int(response)))
def test_context_versioning(self): with open(filepath('test-patch-modify-context.json')) as f: patch = f.read() with self.client as client: res = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) res = client.get('/d.json?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) ctx = json.loads(res.get_data(as_text=True)).get('@context', None) self.assertIsNone(ctx) res = client.get('/c?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) res = client.get('/d.json?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) self.assertEqual( res.headers['Cache-Control'], 'public, max-age={}'.format(cache.LONG_TIME)) ctx = json.loads(res.get_data(as_text=True))['@context'] self.assertEqual(ctx[0], 'http://localhost.localdomain:5000/c?version=1') res = client.get('/c?version=1', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) self.assertEqual( res.headers['Cache-Control'], 'public, max-age={}'.format(cache.LONG_TIME)) ctx = json.loads(res.get_data(as_text=True))['@context'] self.assertNotIn('foobar', ctx) res = client.get('/d.json?version=2', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) ctx = json.loads(res.get_data(as_text=True))['@context'] self.assertEqual(ctx[0], 'http://localhost.localdomain:5000/c?version=2') res = client.get('/c?version=2', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.OK) ctx = json.loads(res.get_data(as_text=True))['@context'] self.assertIn('foobar', ctx)
def test_versioning(self): with open(filepath('test-patch-adds-items.json')) as f: patch1 = f.read() with open(filepath('test-patch-add-period.json')) as f: patch2 = f.read() with self.client as client: res = client.patch( '/d/', data=patch1, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) res = client.patch( '/d/', data=patch2, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res.headers['Location']).path res = client.post( patch_url + 'merge', buffered=True, headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) self.assertEqual(res.status_code, http.client.NO_CONTENT) res = client.get('/trgkv?version=0', headers={'Accept': 'application/json'}, follow_redirects=True) self.assertEqual(res.status_code, http.client.NOT_FOUND) for version in range(1, 4): res = client.get( '/trgkv?version={}'.format(version), headers={'Accept': 'application/json'}) self.assertEqual( res.status_code, http.client.SEE_OTHER) self.assertEqual( '/' + res.headers['Location'].split('/')[-1], '/trgkv.json?version={}'.format(version)) res = client.get( '/trgkv.json?version={}'.format(version)) self.assertEqual( res.status_code, http.client.OK) self.assertEqual( res.headers['Content-Type'], 'application/json') ctx = json.loads(res.get_data(as_text=True))['@context'] self.assertEqual( ctx[0], 'http://localhost.localdomain:5000/c?version={}'.format(version) ) res = client.get('/history.jsonld?inline-context') self.assertEqual( res.headers['Cache-Control'], 'public, max-age=0') self.assertEqual( res.headers['X-Accel-Expires'], '{}'.format(cache.MEDIUM_TIME))
def reset(client) : response = Menu.prompt("Are you sure you want to reset? (Any changes will be lost) [y|n]: ") if response not in ['y', 'n'] : print("Answer must be one of [y|n]") elif response is 'y' : client.post("reset")
def test_get_history(self): with open(filepath('test-patch-adds-items.json')) as f: patch = f.read() with self.client as client: res1 = client.patch( '/d/', data=patch, content_type='application/json', headers={'Authorization': 'Bearer ' + 'NTAwNWViMTgtYmU2Yi00YWMwLWIwODQtMDQ0MzI4OWIzMzc4'}) patch_url = urlparse(res1.headers['Location']).path client.post( patch_url + 'merge', headers={'Authorization': 'Bearer ' + 'ZjdjNjQ1ODQtMDc1MC00Y2I2LThjODEtMjkzMmY1ZGFhYmI4'}) res2 = client.get('/h') self.assertEqual(res2.status_code, http.client.OK) self.assertEqual( res2.headers['Content-Type'], 'application/ld+json') jsonld = res2.get_data(as_text=True) g = ConjunctiveGraph() g.parse(format='json-ld', data=jsonld) # Initial data load self.assertIn( # None means any (PERIODO['p0h#change-1'], PROV.endedAtTime, None), g) self.assertIn( (PERIODO['p0h#change-1'], PROV.used, PERIODO['p0d?version=0']), g) self.assertIn( (PERIODO['p0d?version=0'], PROV.specializationOf, PERIODO['p0d']), g) self.assertIn( (PERIODO['p0h#change-1'], PROV.used, PERIODO['p0h#patch-1']), g) self.assertIn( (PERIODO['p0h#patch-1'], FOAF.page, PERIODO['p0patches/1/patch.jsonpatch']), g) self.assertIn( (PERIODO['p0h#change-1'], PROV.generated, PERIODO['p0d?version=1']), g) self.assertIn( (PERIODO['p0d?version=1'], PROV.specializationOf, PERIODO['p0d']), g) self.assertIn( (PERIODO['p0h#change-1'], PROV.generated, PERIODO['p0trgkv?version=1']), g) self.assertIn( (PERIODO['p0trgkv?version=1'], PROV.specializationOf, PERIODO['p0trgkv']), g) self.assertIn( (PERIODO['p0h#change-1'], PROV.generated, PERIODO['p0trgkvwbjd?version=1']), g) self.assertIn( (PERIODO['p0trgkvwbjd?version=1'], PROV.specializationOf, PERIODO['p0trgkvwbjd']), g) # Change from first submitted patch self.assertIn( # None means any (PERIODO['p0h#change-2'], PROV.startedAtTime, None), g) self.assertIn( # None means any (PERIODO['p0h#change-2'], PROV.endedAtTime, None), g) start = g.value( subject=PERIODO['p0h#change-2'], predicate=PROV.startedAtTime) self.assertEqual(start.datatype, XSD.dateTime) self.assertRegex(start.value.isoformat(), W3CDTF) end = g.value( subject=PERIODO['p0h#change-2'], predicate=PROV.endedAtTime) self.assertEqual(end.datatype, XSD.dateTime) self.assertRegex(end.value.isoformat(), W3CDTF) self.assertIn( (PERIODO['p0h#change-2'], PROV.wasAssociatedWith, URIRef('http://orcid.org/1234-5678-9101-112X')), g) self.assertIn( (PERIODO['p0h#change-2'], PROV.wasAssociatedWith, URIRef('http://orcid.org/1211-1098-7654-321X')), g) for association in g.subjects( predicate=PROV.agent, object=URIRef('http://orcid.org/1234-5678-9101-112X')): role = g.value(subject=association, predicate=PROV.hadRole) self.assertIn(role, (PERIODO['p0v#submitted'], PERIODO['p0v#updated'])) merger = g.value( predicate=PROV.agent, object=URIRef('http://orcid.org/1211-1098-7654-321X')) self.assertIn( (PERIODO['p0h#change-2'], PROV.qualifiedAssociation, merger), g) self.assertIn( (merger, PROV.hadRole, PERIODO['p0v#merged']), g) self.assertIn( (PERIODO['p0h#change-2'], PROV.used, PERIODO['p0d?version=1']), g) self.assertIn( (PERIODO['p0d?version=1'], PROV.specializationOf, PERIODO['p0d']), g) self.assertIn( (PERIODO['p0h#change-2'], PROV.used, PERIODO['p0h#patch-2']), g) self.assertIn( (PERIODO['p0h#patch-2'], FOAF.page, PERIODO['p0patches/2/patch.jsonpatch']), g) self.assertIn( (PERIODO['p0h#change-2'], PROV.generated, PERIODO['p0d?version=2']), g) self.assertIn( (PERIODO['p0d?version=2'], PROV.specializationOf, PERIODO['p0d']), g) self.assertIn( (PERIODO['p0h#change-2'], PROV.generated, PERIODO['p0trgkv?version=2']), g) self.assertIn( (PERIODO['p0trgkv?version=2'], PROV.specializationOf, PERIODO['p0trgkv']), g) self.assertIn( (PERIODO['p0trgkv?version=2'], PROV.wasRevisionOf, PERIODO['p0trgkv?version=1']), g) entities = 0 for _, _, version in g.triples( (PERIODO['p0h#change-2'], PROV.generated, None)): entity = g.value(subject=version, predicate=PROV.specializationOf) self.assertEqual(str(entity) + '?version=2', str(version)) entities += 1 self.assertEqual(entities, 5)
def set_mode(client) : response = Menu.prompt("Enter mode [off|lamp|scheduler]: ") if response not in ['off', 'lamp', 'scheduler'] : print("Mode must be one of [off|lamp|scheduler]") else : client.post("mode?mode={}".format(response))