Repository: getmoto/moto

Issue:
Method organizations.list_accounts don't limit accounts by MaxResults
## Reporting Bugs

When calling `organizations.list_accounts(MaxResults=2)` moto doesn't return only 2 AWS Accounts. It returns all accounts present in the organization.
---

Libraries versions below.
```
moto==3.0.7
boto3==1.21.20
boto3-type-annotations==0.3.1
botocore==1.24.20
```

--- 
### Code to reproduce

```python
organizations.create_organization(FeatureSet="ALL")
for i in range(10):
            organizations.create_account(AccountName=f"AWS_Account_{i}", Email=f"email{i}@mydomain.com")

current_accounts = organizations.list_accounts(MaxResults=2) # returns 10 instead of 2 with "NextToken" as documented here https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/organizations.html#Organizations.Client.list_accounts
```


Discussion:

Patch:
diff --git a/moto/organizations/models.py b/moto/organizations/models.py
--- a/moto/organizations/models.py
+++ b/moto/organizations/models.py
@@ -20,6 +20,8 @@
     PolicyTypeNotEnabledException,
     TargetNotFoundException,
 )
+from moto.utilities.paginator import paginate
+from .utils import PAGINATION_MODEL
 
 
 class FakeOrganization(BaseModel):
@@ -495,8 +497,11 @@ def list_create_account_status(self, **kwargs):
             next_token = str(len(accounts_resp))
         return dict(CreateAccountStatuses=accounts_resp, NextToken=next_token)
 
+    @paginate(pagination_model=PAGINATION_MODEL)
     def list_accounts(self):
-        return dict(Accounts=[account.describe() for account in self.accounts])
+        accounts = [account.describe() for account in self.accounts]
+        accounts = sorted(accounts, key=lambda x: x["JoinedTimestamp"])
+        return accounts
 
     def list_accounts_for_parent(self, **kwargs):
         parent_id = self.validate_parent_id(kwargs["ParentId"])
diff --git a/moto/organizations/responses.py b/moto/organizations/responses.py
--- a/moto/organizations/responses.py
+++ b/moto/organizations/responses.py
@@ -85,7 +85,15 @@ def list_create_account_status(self):
         )
 
     def list_accounts(self):
-        return json.dumps(self.organizations_backend.list_accounts())
+        max_results = self._get_int_param("MaxResults")
+        next_token = self._get_param("NextToken")
+        accounts, next_token = self.organizations_backend.list_accounts(
+            max_results=max_results, next_token=next_token
+        )
+        response = {"Accounts": accounts}
+        if next_token:
+            response["NextToken"] = next_token
+        return json.dumps(response)
 
     def list_accounts_for_parent(self):
         return json.dumps(
diff --git a/moto/organizations/utils.py b/moto/organizations/utils.py
--- a/moto/organizations/utils.py
+++ b/moto/organizations/utils.py
@@ -33,6 +33,16 @@
 CREATE_ACCOUNT_STATUS_ID_REGEX = r"car-[a-z0-9]{%s}" % CREATE_ACCOUNT_STATUS_ID_SIZE
 POLICY_ID_REGEX = r"%s|p-[a-z0-9]{%s}" % (DEFAULT_POLICY_ID, POLICY_ID_SIZE)
 
+PAGINATION_MODEL = {
+    "list_accounts": {
+        "input_token": "next_token",
+        "limit_key": "max_results",
+        "limit_default": 100,
+        "result_key": "Accounts",
+        "unique_attribute": "JoinedTimestamp",
+    },
+}
+
 
 def make_random_org_id():
     # The regex pattern for an organization ID string requires "o-"
diff --git a/moto/utilities/paginator.py b/moto/utilities/paginator.py
--- a/moto/utilities/paginator.py
+++ b/moto/utilities/paginator.py
@@ -137,7 +137,7 @@ def _check_predicate(self, item):
         predicate_values = unique_attributes.split("|")
         for (index, attr) in enumerate(self._unique_attributes):
             curr_val = item[attr] if type(item) == dict else getattr(item, attr, None)
-            if not curr_val == predicate_values[index]:
+            if not str(curr_val) == predicate_values[index]:
                 return False
         return True
 
@@ -148,9 +148,9 @@ def _build_next_token(self, next_item):
         range_keys = []
         for attr in self._unique_attributes:
             if type(next_item) == dict:
-                range_keys.append(next_item[attr])
+                range_keys.append(str(next_item[attr]))
             else:
-                range_keys.append(getattr(next_item, attr))
+                range_keys.append(str(getattr(next_item, attr)))
         token_dict["uniqueAttributes"] = "|".join(range_keys)
         return self._token_encoder.encode(token_dict)
 


Test patch:
diff --git a/tests/test_organizations/test_organizations_boto3.py b/tests/test_organizations/test_organizations_boto3.py
--- a/tests/test_organizations/test_organizations_boto3.py
+++ b/tests/test_organizations/test_organizations_boto3.py
@@ -229,6 +229,25 @@ def test_list_accounts():
     accounts[3]["Email"].should.equal(mockname + "2" + "@" + mockdomain)
 
 
+@mock_organizations
+def test_list_accounts_pagination():
+    client = boto3.client("organizations", region_name="us-east-1")
+    client.create_organization(FeatureSet="ALL")
+    for i in range(25):
+        name = mockname + str(i)
+        email = name + "@" + mockdomain
+        client.create_account(AccountName=name, Email=email)
+    response = client.list_accounts()
+    response.should_not.have.key("NextToken")
+    len(response["Accounts"]).should.be.greater_than_or_equal_to(i)
+
+    paginator = client.get_paginator("list_accounts")
+    page_iterator = paginator.paginate(MaxResults=5)
+    for page in page_iterator:
+        len(page["Accounts"]).should.be.lower_than_or_equal_to(5)
+    page["Accounts"][-1]["Name"].should.contain("24")
+
+
 @mock_organizations
 def test_list_accounts_for_parent():
     client = boto3.client("organizations", region_name="us-east-1")