mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-23 10:03:54 +03:00
fix: run the tests in python 3.12 and 3.13 and remove snapshottest
dependency (#1572)
* actually run the tests in python 3.12 and 3.13 * remove snapshottest from the example tests so that the tests pass in 3.12 and 3.13 again * remove the section about snapshot testing from the testing docs because the snapshottest package doesn't work on Python 3.12 and above * fix assertion for badly formed JSON input on Python 3.13 * fix deprecation warning about datetime.utcfromtimestamp()
This commit is contained in:
parent
dc3b2e49c1
commit
48678afba4
|
@ -69,43 +69,3 @@ You can also add extra keyword arguments to the ``execute`` method, such as
|
|||
'hey': 'hello Peter!'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Snapshot testing
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
As our APIs evolve, we need to know when our changes introduce any breaking changes that might break
|
||||
some of the clients of our GraphQL app.
|
||||
|
||||
However, writing tests and replicating the same response we expect from our GraphQL application can be a
|
||||
tedious and repetitive task, and sometimes it's easier to skip this process.
|
||||
|
||||
Because of that, we recommend the usage of `SnapshotTest <https://github.com/syrusakbary/snapshottest/>`_.
|
||||
|
||||
SnapshotTest lets us write all these tests in a breeze, as it automatically creates the ``snapshots`` for us
|
||||
the first time the test are executed.
|
||||
|
||||
|
||||
Here is a simple example on how our tests will look if we use ``pytest``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
def test_hey(snapshot):
|
||||
client = Client(my_schema)
|
||||
# This will create a snapshot dir and a snapshot file
|
||||
# the first time the test is executed, with the response
|
||||
# of the execution.
|
||||
snapshot.assert_match(client.execute('''{ hey }'''))
|
||||
|
||||
|
||||
If we are using ``unittest``:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from snapshottest import TestCase
|
||||
|
||||
class APITestCase(TestCase):
|
||||
def test_api_me(self):
|
||||
"""Testing the API for /me"""
|
||||
client = Client(my_schema)
|
||||
self.assertMatchSnapshot(client.execute('''{ hey }'''))
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
||||
from snapshottest import Snapshot
|
||||
|
||||
snapshots = Snapshot()
|
||||
|
||||
snapshots["test_hero_name_query 1"] = {"data": {"hero": {"name": "R2-D2"}}}
|
||||
|
||||
snapshots["test_hero_name_and_friends_query 1"] = {
|
||||
"data": {
|
||||
"hero": {
|
||||
"id": "2001",
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Han Solo"},
|
||||
{"name": "Leia Organa"},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snapshots["test_nested_query 1"] = {
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Luke Skywalker",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Han Solo"},
|
||||
{"name": "Leia Organa"},
|
||||
{"name": "C-3PO"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Han Solo",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Leia Organa"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Leia Organa",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Han Solo"},
|
||||
{"name": "C-3PO"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snapshots["test_fetch_luke_query 1"] = {"data": {"human": {"name": "Luke Skywalker"}}}
|
||||
|
||||
snapshots["test_fetch_some_id_query 1"] = {
|
||||
"data": {"human": {"name": "Luke Skywalker"}}
|
||||
}
|
||||
|
||||
snapshots["test_fetch_some_id_query2 1"] = {"data": {"human": {"name": "Han Solo"}}}
|
||||
|
||||
snapshots["test_invalid_id_query 1"] = {"data": {"human": None}}
|
||||
|
||||
snapshots["test_fetch_luke_aliased 1"] = {"data": {"luke": {"name": "Luke Skywalker"}}}
|
||||
|
||||
snapshots["test_fetch_luke_and_leia_aliased 1"] = {
|
||||
"data": {"luke": {"name": "Luke Skywalker"}, "leia": {"name": "Leia Organa"}}
|
||||
}
|
||||
|
||||
snapshots["test_duplicate_fields 1"] = {
|
||||
"data": {
|
||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||
}
|
||||
}
|
||||
|
||||
snapshots["test_use_fragment 1"] = {
|
||||
"data": {
|
||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||
}
|
||||
}
|
||||
|
||||
snapshots["test_check_type_of_r2 1"] = {
|
||||
"data": {"hero": {"__typename": "Droid", "name": "R2-D2"}}
|
||||
}
|
||||
|
||||
snapshots["test_check_type_of_luke 1"] = {
|
||||
"data": {"hero": {"__typename": "Human", "name": "Luke Skywalker"}}
|
||||
}
|
|
@ -8,19 +8,19 @@ setup()
|
|||
client = Client(schema)
|
||||
|
||||
|
||||
def test_hero_name_query(snapshot):
|
||||
query = """
|
||||
def test_hero_name_query():
|
||||
result = client.execute("""
|
||||
query HeroNameQuery {
|
||||
hero {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {"data": {"hero": {"name": "R2-D2"}}}
|
||||
|
||||
|
||||
def test_hero_name_and_friends_query(snapshot):
|
||||
query = """
|
||||
def test_hero_name_and_friends_query():
|
||||
result = client.execute("""
|
||||
query HeroNameAndFriendsQuery {
|
||||
hero {
|
||||
id
|
||||
|
@ -30,12 +30,24 @@ def test_hero_name_and_friends_query(snapshot):
|
|||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"hero": {
|
||||
"id": "2001",
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Han Solo"},
|
||||
{"name": "Leia Organa"},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_nested_query(snapshot):
|
||||
query = """
|
||||
def test_nested_query():
|
||||
result = client.execute("""
|
||||
query NestedQuery {
|
||||
hero {
|
||||
name
|
||||
|
@ -48,70 +60,113 @@ def test_nested_query(snapshot):
|
|||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Luke Skywalker",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Han Solo"},
|
||||
{"name": "Leia Organa"},
|
||||
{"name": "C-3PO"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Han Solo",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Leia Organa"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Leia Organa",
|
||||
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Han Solo"},
|
||||
{"name": "C-3PO"},
|
||||
{"name": "R2-D2"},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_fetch_luke_query(snapshot):
|
||||
query = """
|
||||
def test_fetch_luke_query():
|
||||
result = client.execute("""
|
||||
query FetchLukeQuery {
|
||||
human(id: "1000") {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {"data": {"human": {"name": "Luke Skywalker"}}}
|
||||
|
||||
|
||||
def test_fetch_some_id_query(snapshot):
|
||||
query = """
|
||||
def test_fetch_some_id_query():
|
||||
result = client.execute(
|
||||
"""
|
||||
query FetchSomeIDQuery($someId: String!) {
|
||||
human(id: $someId) {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
params = {"someId": "1000"}
|
||||
snapshot.assert_match(client.execute(query, variables=params))
|
||||
""",
|
||||
variables={"someId": "1000"},
|
||||
)
|
||||
assert result == {"data": {"human": {"name": "Luke Skywalker"}}}
|
||||
|
||||
|
||||
def test_fetch_some_id_query2(snapshot):
|
||||
query = """
|
||||
def test_fetch_some_id_query2():
|
||||
result = client.execute(
|
||||
"""
|
||||
query FetchSomeIDQuery($someId: String!) {
|
||||
human(id: $someId) {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
params = {"someId": "1002"}
|
||||
snapshot.assert_match(client.execute(query, variables=params))
|
||||
""",
|
||||
variables={"someId": "1002"},
|
||||
)
|
||||
assert result == {"data": {"human": {"name": "Han Solo"}}}
|
||||
|
||||
|
||||
def test_invalid_id_query(snapshot):
|
||||
query = """
|
||||
def test_invalid_id_query():
|
||||
result = client.execute(
|
||||
"""
|
||||
query humanQuery($id: String!) {
|
||||
human(id: $id) {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
params = {"id": "not a valid id"}
|
||||
snapshot.assert_match(client.execute(query, variables=params))
|
||||
""",
|
||||
variables={"id": "not a valid id"},
|
||||
)
|
||||
assert result == {"data": {"human": None}}
|
||||
|
||||
|
||||
def test_fetch_luke_aliased(snapshot):
|
||||
query = """
|
||||
def test_fetch_luke_aliased():
|
||||
result = client.execute("""
|
||||
query FetchLukeAliased {
|
||||
luke: human(id: "1000") {
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {"data": {"luke": {"name": "Luke Skywalker"}}}
|
||||
|
||||
|
||||
def test_fetch_luke_and_leia_aliased(snapshot):
|
||||
query = """
|
||||
def test_fetch_luke_and_leia_aliased():
|
||||
result = client.execute("""
|
||||
query FetchLukeAndLeiaAliased {
|
||||
luke: human(id: "1000") {
|
||||
name
|
||||
|
@ -120,12 +175,14 @@ def test_fetch_luke_and_leia_aliased(snapshot):
|
|||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {"luke": {"name": "Luke Skywalker"}, "leia": {"name": "Leia Organa"}}
|
||||
}
|
||||
|
||||
|
||||
def test_duplicate_fields(snapshot):
|
||||
query = """
|
||||
def test_duplicate_fields():
|
||||
result = client.execute("""
|
||||
query DuplicateFields {
|
||||
luke: human(id: "1000") {
|
||||
name
|
||||
|
@ -136,12 +193,17 @@ def test_duplicate_fields(snapshot):
|
|||
homePlanet
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_use_fragment(snapshot):
|
||||
query = """
|
||||
def test_use_fragment():
|
||||
result = client.execute("""
|
||||
query UseFragment {
|
||||
luke: human(id: "1000") {
|
||||
...HumanFragment
|
||||
|
@ -154,29 +216,36 @@ def test_use_fragment(snapshot):
|
|||
name
|
||||
homePlanet
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
|
||||
"leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_check_type_of_r2(snapshot):
|
||||
query = """
|
||||
def test_check_type_of_r2():
|
||||
result = client.execute("""
|
||||
query CheckTypeOfR2 {
|
||||
hero {
|
||||
__typename
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {"data": {"hero": {"__typename": "Droid", "name": "R2-D2"}}}
|
||||
|
||||
|
||||
def test_check_type_of_luke(snapshot):
|
||||
query = """
|
||||
def test_check_type_of_luke():
|
||||
result = client.execute("""
|
||||
query CheckTypeOfLuke {
|
||||
hero(episode: EMPIRE) {
|
||||
__typename
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {"hero": {"__typename": "Human", "name": "Luke Skywalker"}}
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
||||
from snapshottest import Snapshot
|
||||
|
||||
snapshots = Snapshot()
|
||||
|
||||
snapshots["test_correct_fetch_first_ship_rebels 1"] = {
|
||||
"data": {
|
||||
"rebels": {
|
||||
"name": "Alliance to Restore the Republic",
|
||||
"ships": {
|
||||
"pageInfo": {
|
||||
"startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||
"endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||
"hasNextPage": True,
|
||||
"hasPreviousPage": False,
|
||||
},
|
||||
"edges": [
|
||||
{"cursor": "YXJyYXljb25uZWN0aW9uOjA=", "node": {"name": "X-Wing"}}
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
||||
from snapshottest import Snapshot
|
||||
|
||||
snapshots = Snapshot()
|
||||
|
||||
snapshots["test_mutations 1"] = {
|
||||
"data": {
|
||||
"introduceShip": {
|
||||
"ship": {"id": "U2hpcDo5", "name": "Peter"},
|
||||
"faction": {
|
||||
"name": "Alliance to Restore the Republic",
|
||||
"ships": {
|
||||
"edges": [
|
||||
{"node": {"id": "U2hpcDox", "name": "X-Wing"}},
|
||||
{"node": {"id": "U2hpcDoy", "name": "Y-Wing"}},
|
||||
{"node": {"id": "U2hpcDoz", "name": "A-Wing"}},
|
||||
{"node": {"id": "U2hpcDo0", "name": "Millennium Falcon"}},
|
||||
{"node": {"id": "U2hpcDo1", "name": "Home One"}},
|
||||
{"node": {"id": "U2hpcDo5", "name": "Peter"}},
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# snapshottest: v1 - https://goo.gl/zC4yUc
|
||||
from snapshottest import Snapshot
|
||||
|
||||
|
||||
snapshots = Snapshot()
|
||||
|
||||
snapshots["test_correctly_fetches_id_name_rebels 1"] = {
|
||||
"data": {
|
||||
"rebels": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
||||
}
|
||||
}
|
||||
|
||||
snapshots["test_correctly_refetches_rebels 1"] = {
|
||||
"data": {"node": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}}
|
||||
}
|
||||
|
||||
snapshots["test_correctly_fetches_id_name_empire 1"] = {
|
||||
"data": {"empire": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||
}
|
||||
|
||||
snapshots["test_correctly_refetches_empire 1"] = {
|
||||
"data": {"node": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||
}
|
||||
|
||||
snapshots["test_correctly_refetches_xwing 1"] = {
|
||||
"data": {"node": {"id": "U2hpcDox", "name": "X-Wing"}}
|
||||
}
|
||||
|
||||
snapshots["test_str_schema 1"] = '''type Query {
|
||||
rebels: Faction
|
||||
empire: Faction
|
||||
node(
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
): Node
|
||||
}
|
||||
|
||||
"""A faction in the Star Wars saga"""
|
||||
type Faction implements Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
|
||||
"""The name of the faction."""
|
||||
name: String
|
||||
|
||||
"""The ships used by the faction."""
|
||||
ships(before: String, after: String, first: Int, last: Int): ShipConnection
|
||||
}
|
||||
|
||||
"""An object with an ID"""
|
||||
interface Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type ShipConnection {
|
||||
"""Pagination data for this connection."""
|
||||
pageInfo: PageInfo!
|
||||
|
||||
"""Contains the nodes in this connection."""
|
||||
edges: [ShipEdge]!
|
||||
}
|
||||
|
||||
"""
|
||||
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
|
||||
"""
|
||||
type PageInfo {
|
||||
"""When paginating forwards, are there more items?"""
|
||||
hasNextPage: Boolean!
|
||||
|
||||
"""When paginating backwards, are there more items?"""
|
||||
hasPreviousPage: Boolean!
|
||||
|
||||
"""When paginating backwards, the cursor to continue."""
|
||||
startCursor: String
|
||||
|
||||
"""When paginating forwards, the cursor to continue."""
|
||||
endCursor: String
|
||||
}
|
||||
|
||||
"""A Relay edge containing a `Ship` and its cursor."""
|
||||
type ShipEdge {
|
||||
"""The item at the end of the edge"""
|
||||
node: Ship
|
||||
|
||||
"""A cursor for use in pagination"""
|
||||
cursor: String!
|
||||
}
|
||||
|
||||
"""A ship in the Star Wars saga"""
|
||||
type Ship implements Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
|
||||
"""The name of the ship."""
|
||||
name: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
introduceShip(input: IntroduceShipInput!): IntroduceShipPayload
|
||||
}
|
||||
|
||||
type IntroduceShipPayload {
|
||||
ship: Ship
|
||||
faction: Faction
|
||||
clientMutationId: String
|
||||
}
|
||||
|
||||
input IntroduceShipInput {
|
||||
shipName: String!
|
||||
factionId: String!
|
||||
clientMutationId: String
|
||||
}'''
|
|
@ -8,26 +8,46 @@ setup()
|
|||
client = Client(schema)
|
||||
|
||||
|
||||
def test_correct_fetch_first_ship_rebels(snapshot):
|
||||
query = """
|
||||
query RebelsShipsQuery {
|
||||
rebels {
|
||||
name,
|
||||
ships(first: 1) {
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
}
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
name
|
||||
def test_correct_fetch_first_ship_rebels():
|
||||
result = client.execute("""
|
||||
query RebelsShipsQuery {
|
||||
rebels {
|
||||
name,
|
||||
ships(first: 1) {
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
}
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"rebels": {
|
||||
"name": "Alliance to Restore the Republic",
|
||||
"ships": {
|
||||
"pageInfo": {
|
||||
"startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||
"endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||
"hasNextPage": True,
|
||||
"hasPreviousPage": False,
|
||||
},
|
||||
"edges": [
|
||||
{
|
||||
"cursor": "YXJyYXljb25uZWN0aW9uOjA=",
|
||||
"node": {"name": "X-Wing"},
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
|
|
|
@ -8,26 +8,45 @@ setup()
|
|||
client = Client(schema)
|
||||
|
||||
|
||||
def test_mutations(snapshot):
|
||||
query = """
|
||||
mutation MyMutation {
|
||||
introduceShip(input:{clientMutationId:"abc", shipName: "Peter", factionId: "1"}) {
|
||||
ship {
|
||||
id
|
||||
name
|
||||
}
|
||||
faction {
|
||||
name
|
||||
ships {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
def test_mutations():
|
||||
result = client.execute("""
|
||||
mutation MyMutation {
|
||||
introduceShip(input:{clientMutationId:"abc", shipName: "Peter", factionId: "1"}) {
|
||||
ship {
|
||||
id
|
||||
name
|
||||
}
|
||||
faction {
|
||||
name
|
||||
ships {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"introduceShip": {
|
||||
"ship": {"id": "U2hpcDo5", "name": "Peter"},
|
||||
"faction": {
|
||||
"name": "Alliance to Restore the Republic",
|
||||
"ships": {
|
||||
"edges": [
|
||||
{"node": {"id": "U2hpcDox", "name": "X-Wing"}},
|
||||
{"node": {"id": "U2hpcDoy", "name": "Y-Wing"}},
|
||||
{"node": {"id": "U2hpcDoz", "name": "A-Wing"}},
|
||||
{"node": {"id": "U2hpcDo0", "name": "Millennium Falcon"}},
|
||||
{"node": {"id": "U2hpcDo1", "name": "Home One"}},
|
||||
{"node": {"id": "U2hpcDo5", "name": "Peter"}},
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import textwrap
|
||||
|
||||
from graphene.test import Client
|
||||
|
||||
from ..data import setup
|
||||
|
@ -8,24 +10,115 @@ setup()
|
|||
client = Client(schema)
|
||||
|
||||
|
||||
def test_str_schema(snapshot):
|
||||
snapshot.assert_match(str(schema).strip())
|
||||
def test_str_schema():
|
||||
assert str(schema).strip() == textwrap.dedent(
|
||||
'''\
|
||||
type Query {
|
||||
rebels: Faction
|
||||
empire: Faction
|
||||
node(
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
): Node
|
||||
}
|
||||
|
||||
"""A faction in the Star Wars saga"""
|
||||
type Faction implements Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
|
||||
"""The name of the faction."""
|
||||
name: String
|
||||
|
||||
"""The ships used by the faction."""
|
||||
ships(before: String, after: String, first: Int, last: Int): ShipConnection
|
||||
}
|
||||
|
||||
"""An object with an ID"""
|
||||
interface Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type ShipConnection {
|
||||
"""Pagination data for this connection."""
|
||||
pageInfo: PageInfo!
|
||||
|
||||
"""Contains the nodes in this connection."""
|
||||
edges: [ShipEdge]!
|
||||
}
|
||||
|
||||
"""
|
||||
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
|
||||
"""
|
||||
type PageInfo {
|
||||
"""When paginating forwards, are there more items?"""
|
||||
hasNextPage: Boolean!
|
||||
|
||||
"""When paginating backwards, are there more items?"""
|
||||
hasPreviousPage: Boolean!
|
||||
|
||||
"""When paginating backwards, the cursor to continue."""
|
||||
startCursor: String
|
||||
|
||||
"""When paginating forwards, the cursor to continue."""
|
||||
endCursor: String
|
||||
}
|
||||
|
||||
"""A Relay edge containing a `Ship` and its cursor."""
|
||||
type ShipEdge {
|
||||
"""The item at the end of the edge"""
|
||||
node: Ship
|
||||
|
||||
"""A cursor for use in pagination"""
|
||||
cursor: String!
|
||||
}
|
||||
|
||||
"""A ship in the Star Wars saga"""
|
||||
type Ship implements Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
|
||||
"""The name of the ship."""
|
||||
name: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
introduceShip(input: IntroduceShipInput!): IntroduceShipPayload
|
||||
}
|
||||
|
||||
type IntroduceShipPayload {
|
||||
ship: Ship
|
||||
faction: Faction
|
||||
clientMutationId: String
|
||||
}
|
||||
|
||||
input IntroduceShipInput {
|
||||
shipName: String!
|
||||
factionId: String!
|
||||
clientMutationId: String
|
||||
}'''
|
||||
)
|
||||
|
||||
|
||||
def test_correctly_fetches_id_name_rebels(snapshot):
|
||||
query = """
|
||||
def test_correctly_fetches_id_name_rebels():
|
||||
result = client.execute("""
|
||||
query RebelsQuery {
|
||||
rebels {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"rebels": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_correctly_refetches_rebels(snapshot):
|
||||
query = """
|
||||
def test_correctly_refetches_rebels():
|
||||
result = client.execute("""
|
||||
query RebelsRefetchQuery {
|
||||
node(id: "RmFjdGlvbjox") {
|
||||
id
|
||||
|
@ -34,24 +127,30 @@ def test_correctly_refetches_rebels(snapshot):
|
|||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {
|
||||
"node": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_correctly_fetches_id_name_empire(snapshot):
|
||||
query = """
|
||||
def test_correctly_fetches_id_name_empire():
|
||||
result = client.execute("""
|
||||
query EmpireQuery {
|
||||
empire {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {"empire": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||
}
|
||||
|
||||
|
||||
def test_correctly_refetches_empire(snapshot):
|
||||
query = """
|
||||
def test_correctly_refetches_empire():
|
||||
result = client.execute("""
|
||||
query EmpireRefetchQuery {
|
||||
node(id: "RmFjdGlvbjoy") {
|
||||
id
|
||||
|
@ -60,12 +159,14 @@ def test_correctly_refetches_empire(snapshot):
|
|||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {
|
||||
"data": {"node": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
|
||||
}
|
||||
|
||||
|
||||
def test_correctly_refetches_xwing(snapshot):
|
||||
query = """
|
||||
def test_correctly_refetches_xwing():
|
||||
result = client.execute("""
|
||||
query XWingRefetchQuery {
|
||||
node(id: "U2hpcDox") {
|
||||
id
|
||||
|
@ -74,5 +175,5 @@ def test_correctly_refetches_xwing(snapshot):
|
|||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
snapshot.assert_match(client.execute(query))
|
||||
""")
|
||||
assert result == {"data": {"node": {"id": "U2hpcDox", "name": "X-Wing"}}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# https://github.com/graphql-python/graphene/issues/1293
|
||||
|
||||
import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import graphene
|
||||
from graphql.utilities import print_schema
|
||||
|
@ -9,11 +9,11 @@ from graphql.utilities import print_schema
|
|||
class Filters(graphene.InputObjectType):
|
||||
datetime_after = graphene.DateTime(
|
||||
required=False,
|
||||
default_value=datetime.datetime.utcfromtimestamp(1434549820776 / 1000),
|
||||
default_value=datetime.fromtimestamp(1434549820.776, timezone.utc),
|
||||
)
|
||||
datetime_before = graphene.DateTime(
|
||||
required=False,
|
||||
default_value=datetime.datetime.utcfromtimestamp(1444549820776 / 1000),
|
||||
default_value=datetime.fromtimestamp(1444549820.776, timezone.utc),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -51,35 +51,30 @@ def test_jsonstring_invalid_query():
|
|||
Test that if an invalid type is provided we get an error
|
||||
"""
|
||||
result = schema.execute("{ json(input: 1) }")
|
||||
assert result.errors
|
||||
assert len(result.errors) == 1
|
||||
assert result.errors[0].message == "Expected value of type 'JSONString', found 1."
|
||||
assert result.errors == [
|
||||
{"message": "Expected value of type 'JSONString', found 1."},
|
||||
]
|
||||
|
||||
result = schema.execute("{ json(input: {}) }")
|
||||
assert result.errors
|
||||
assert len(result.errors) == 1
|
||||
assert result.errors[0].message == "Expected value of type 'JSONString', found {}."
|
||||
assert result.errors == [
|
||||
{"message": "Expected value of type 'JSONString', found {}."},
|
||||
]
|
||||
|
||||
result = schema.execute('{ json(input: "a") }')
|
||||
assert result.errors
|
||||
assert len(result.errors) == 1
|
||||
assert result.errors[0].message == (
|
||||
"Expected value of type 'JSONString', found \"a\"; "
|
||||
"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)"
|
||||
)
|
||||
assert result.errors == [
|
||||
{
|
||||
"message": "Expected value of type 'JSONString', found \"a\"; "
|
||||
"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)",
|
||||
},
|
||||
]
|
||||
|
||||
result = schema.execute("""{ json(input: "{\\'key\\': 0}") }""")
|
||||
assert result.errors
|
||||
assert len(result.errors) == 1
|
||||
assert (
|
||||
result.errors[0].message
|
||||
== "Syntax Error: Invalid character escape sequence: '\\''."
|
||||
)
|
||||
assert result.errors == [
|
||||
{"message": "Syntax Error: Invalid character escape sequence: '\\''."},
|
||||
]
|
||||
|
||||
result = schema.execute("""{ json(input: "{\\"key\\": 0,}") }""")
|
||||
assert result.errors
|
||||
assert len(result.errors) == 1
|
||||
assert result.errors[0].message == (
|
||||
'Expected value of type \'JSONString\', found "{\\"key\\": 0,}"; '
|
||||
"Badly formed JSONString: Expecting property name enclosed in double quotes: line 1 column 11 (char 10)"
|
||||
assert result.errors[0].message.startswith(
|
||||
'Expected value of type \'JSONString\', found "{\\"key\\": 0,}"; Badly formed JSONString:'
|
||||
)
|
||||
|
|
1
setup.py
1
setup.py
|
@ -50,7 +50,6 @@ tests_require = [
|
|||
"pytest-cov>=5,<6",
|
||||
"pytest-mock>=3,<4",
|
||||
"pytest-asyncio>=0.16,<2",
|
||||
"snapshottest>=0.6,<1",
|
||||
"coveralls>=3.3,<5",
|
||||
]
|
||||
|
||||
|
|
4
tox.ini
4
tox.ini
|
@ -5,10 +5,8 @@ skipsdist = true
|
|||
[testenv]
|
||||
deps =
|
||||
.[test]
|
||||
setenv =
|
||||
PYTHONPATH = .:{envdir}
|
||||
commands =
|
||||
py{38,39,310,311,12,13}: pytest --cov=graphene graphene --cov-report=term --cov-report=xml examples {posargs}
|
||||
pytest --cov=graphene graphene --cov-report=term --cov-report=xml examples {posargs}
|
||||
|
||||
[testenv:pre-commit]
|
||||
basepython = python3.10
|
||||
|
|
Loading…
Reference in New Issue
Block a user