Skip to content

Commit

Permalink
feat(api): add webendpoints to graphql api
Browse files Browse the repository at this point in the history
  • Loading branch information
Collinbrown95 committed Nov 8, 2023
1 parent b130b6e commit aaf1110
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 6 deletions.
58 changes: 58 additions & 0 deletions api/src/graphql_types/mutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,64 @@ def githubEndpoint(self, endpoint: GithubEndpointInput) -> str:

@strawberry.mutation
def webEndpoint(self, endpoint: WebEndpointInput) -> str:
"""
# Update/Insert Web Endpoint
Insert a Web Endpoint with "upsert" semantics.
# Example
```graphql
mutation {
webEndpoint(
endpoint: {
url: "https://some-webapp.canada.ca"
kind: "Web"
accessibility: [
{
url: "https://some-webapp.canada.ca/about",
areaAlt: {
checkPasses: null,
metadata: {
description: "Ensures <area> elements of image maps have alternate text",
helpUrl: "https://dequeuniversity.com/rules/axe/4.8/area-alt?application=axe-puppeteer"
}
},
ariaBrailleEquivalent: {
checkPasses: "false",
metadata: {
description: "Ensure aria-braillelabel and aria-brailleroledescription have a non-braille equivalent",
helpUrl: "https://dequeuniversity.com/rules/axe/4.8/aria-braille-equivalent?application=axe-puppeteer"
}
},
ariaCommandName: {
checkPasses: null,
metadata: {
description: "Ensures every ARIA button, link and menuitem has an accessible name",
helpUrl: "https://dequeuniversity.com/rules/axe/4.8/aria-command-name?application=axe-puppeteer"
}
},
ariaHiddenFocus: {
checkPasses: "true",
metadata: {
description: "Ensures aria-hidden elements are not focusable nor contain focusable elements",
helpUrl: "https://dequeuniversity.com/rules/axe/4.8/aria-hidden-focus?application=axe-puppeteer"
}
},
ariaMeterName: {
checkPasses: "incomplete",
metadata: {
description: "Ensures every ARIA meter node has an accessible name",
helpUrl: "https://dequeuniversity.com/rules/axe/4.8/aria-meter-name?application=axe-puppeteer"
}
}
}
]
}
)
}
```
"""
client = GraphDB()
client.upsert_scanner_endpoint(endpoint)
client.close()
Expand Down
105 changes: 103 additions & 2 deletions api/src/graphql_types/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

from typing import List

from graphql_types.typedef import Endpoint, GithubEndpoint, WebEndpoint
from graphql_types.typedef import Endpoint, GithubEndpoint, WebEndpoint, Accessibility, AccessibilityCheckPasses


@strawberry.type
class Query:
@strawberry.field
def github_endpoint(self, url: str) -> GithubEndpoint:
"""
# Get properties of a Single Github Endpoint
# Get Properties of a Single Github Endpoint
Given a url, retrieves the properties of a single Github Endpoint.
Expand Down Expand Up @@ -70,6 +70,107 @@ def github_endpoints(self, limit: int) -> List[GithubEndpoint]:
endpoint.pop("_id", None)
endpoint.pop("_rev", None)
return [GithubEndpoint(**endpoint) for endpoint in endpoints]

@strawberry.field
def web_endpoint(self, url: str) -> WebEndpoint:
"""
# Get Properties of a Single Web Endpoint
Given a url, retrieves the properties of a single Web Endpoint.
# Example
```graphql
query {
webEndpoint(url: "https://safeinputs.phac.alpha.canada.ca") {
url
accessibility {
url
areaAlt {
checkPasses
metadata
}
}
}
}
```
"""
client = GraphDB()
endpoint = client.get_scanner_endpoint(url)
client.close()
# Remove unecessary db fields from the endpoint dict
endpoint.pop("_id", None)
endpoint.pop("_rev", None)
# Strawberry doesn't recursively resolve fields. The code below
# is a workaround to recursively resolve the accessibility field
# and the "check passes" fields contained within.
return WebEndpoint(
url=endpoint['url'],
kind=endpoint['kind'],
_key=endpoint['_key'],
accessibility=[
Accessibility(**{
k: AccessibilityCheckPasses(**v)
for k, v in ep.items()
if type(v) is not str
},
url=ep['url'])
for ep in endpoint['accessibility']
]
)

@strawberry.field
def web_endpoints(self, limit: int) -> List[WebEndpoint]:
"""
# Get Multiple Web Endpoints
Retrieves a list of Web Endpoints. The number of endpoints returned is
determined by the `limit` parameter.
# Example
```graphql
query {
webEndpoints(limit: 10) {
url
accessibility {
url
areaAlt {
checkPasses
metadata
}
}
}
}
```
"""
client = GraphDB()
endpoints = client.get_scanner_endpoints("Web", limit)
client.close()
# Remove unecessary db fields from the endpoint dict
for endpoint in endpoints:
endpoint.pop("_id", None)
endpoint.pop("_rev", None)
# Strawberry doesn't recursively resolve fields. The code below
# is a workaround to recursively resolve the accessibility field
# and the "check passes" fields contained within.
return [
WebEndpoint(
url=endpoint['url'],
kind=endpoint['kind'],
_key=endpoint['_key'],
accessibility=[
Accessibility(**{
k: AccessibilityCheckPasses(**v)
for k, v in ep.items()
if type(v) is not str
},
url=ep['url'])
for ep in endpoint['accessibility']
]
)
for endpoint in endpoints
]

@strawberry.field
def endpoints(self, urls: List[str]) -> List[Endpoint]:
Expand Down
14 changes: 10 additions & 4 deletions api/src/graphql_types/typedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ class CheckPasses:
check_passes: Optional[bool]
metadata: Optional[JSON]

@strawberry.type
class AccessibilityCheckPasses:
check_passes: Optional[str] # true, false, incomplete, or null
metadata: Optional[JSON]

@strawberry.type
class GithubEndpoint(Endpoint):
url: str
Expand All @@ -38,13 +43,13 @@ class GithubEndpoint(Endpoint):
has_dependabot_yaml: CheckPasses

@strawberry.type
class AccessibilityInput:
class Accessibility:
url: str
area_alt: Optional[CheckPasses]
aria_braille_equivalent: Optional[CheckPasses]
aria_command_name: Optional[CheckPasses]
aria_hidden_focus: Optional[CheckPasses]
aria_input_field: Optional[CheckPasses]
aria_input_field_name: Optional[CheckPasses]
aria_meter_name: Optional[CheckPasses]
aria_progressbar_name: Optional[CheckPasses]
aria_required_children: Optional[CheckPasses]
Expand Down Expand Up @@ -76,7 +81,7 @@ class AccessibilityInput:
server_side_image_map: Optional[CheckPasses]
svg_img_alt: Optional[CheckPasses]
td_headers_attr: Optional[CheckPasses]
td_has_data_cells: Optional[CheckPasses]
th_has_data_cells: Optional[CheckPasses]
valid_lang: Optional[CheckPasses]
video_caption: Optional[CheckPasses]
no_autoplay_audio: Optional[CheckPasses]
Expand Down Expand Up @@ -105,4 +110,5 @@ class AccessibilityInput:
class WebEndpoint(Endpoint):
url: str
kind: str
accessibility: Optional[List[AccessibilityInput]]
_key: str
accessibility: Optional[List[Accessibility]]

0 comments on commit aaf1110

Please sign in to comment.