Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a listZones method to "high-level" interface #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/zones.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,28 @@
config = api.config
config["follow_pagination"] = True

######################
# LISTING ZONES #
######################

# The zone list endpoint does not have full information about each zone,
# so the high-level `listZone` method returns a list of "unloaded" Zone
# objects, and you need to call the `.load` method on any that you intend
# use further.
# It's often easier to use the rest interface directly for list() calls,
# and/or skip right to loadZone, but this could be a reasonable method to use
# for actions that require operating on most of all of your zones.
zone_list = api.listZones()

######################
# LOAD / CREATE ZONE #
######################

# get a zone from the list and load it. this is not a practical way to fetch
# a single zone
listed_zone = [x for x in zone_list if x["zone"] == "test.com"][0]
listed_zone.load()

# to load an existing zone, get a Zone object back
test_zone = api.loadZone("test.com")

Expand Down
14 changes: 14 additions & 0 deletions ns1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,20 @@ def apikey(self):
return ns1.rest.apikey.APIKey(self.config)

# HIGH LEVEL INTERFACE
def listZones(self, callback=None, errback=None):
"""
Returns a list of Zone objects for all of your zones. Note that
to avoid needless API traffic, these are NOT "loaded", and you
will need to call the `.load` method on any that you intend to use
further.

:rtype: list of :py:class:`ns1.zones.Zone`
"""
import ns1.zones

zones = ns1.rest.zones.Zones(self.config)
return [ns1.zones.Zone(self.config, z["zone"]) for z in zones.list()]

def loadZone(self, zone, callback=None, errback=None):
"""
Load an existing zone into a high level Zone object.
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/test_init.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import mock
import pytest

from ns1 import NS1
Expand All @@ -18,6 +19,7 @@
from ns1.rest.team import Team
from ns1.rest.user import User
from ns1.rest.zones import Zones
from ns1.zones import Zone


@pytest.fixture
Expand Down Expand Up @@ -67,3 +69,28 @@ def test_rest_interface(ns1_config, method, want):
client = NS1(config=ns1_config)
got = getattr(client, method)()
assert isinstance(got, want)


@mock.patch.object(Zone, "load")
@mock.patch.object(Zones, "list")
def test_listZones(zones_list, zone_load, ns1_config):
zones_list.return_value = [{"zone": "a.com"}, {"zone": "b.com"}]
client = NS1(config=ns1_config)

result = client.listZones()
zones_list.assert_called_once_with()
zone_load.assert_not_called()
assert sorted([x.zone for x in result]) == ["a.com", "b.com"]

result[0].load()
zone_load.assert_called_once_with()


@mock.patch.object(Zone, "load")
def test_loadZone(zone_load, ns1_config):
zone_load.return_value = "LOADED_ZONE_OBJECT"
client = NS1(config=ns1_config)

result = client.loadZone("a.com")
zone_load.assert_called_once_with(callback=None, errback=None)
assert result == "LOADED_ZONE_OBJECT"