Skip to content

Fix compliance violations pagination so it paginates all sort options properly

What does this MR do and why?

This MR adds offset pagination to the resolver for sorting options that are more complicated than what keyset pagination can handle.

This fixes the issue where the pagination and sorting options were out of sync. It uses the same approach as outlined in https://docs.gitlab.com/ee/development/graphql_guide/pagination.html#offset-pagination-1 and updates the specs to make sure we're using the right pagination type for each sorting option.

GraphQL query

Query
query getComplianceViolations($fullPath: ID!, $filters: ComplianceViolationInput, $sort: ComplianceViolationSort, $after: String, $before: String, $first: Int) {
  group(fullPath: $fullPath) {
    id
    mergeRequestViolations(
      filters: $filters
      sort: $sort
      after: $after
      before: $before
      first: $first
    ) {
      nodes {
        id
        severityLevel
        reason
        violatingUser {
          id
          name
          username
          avatarUrl
          webUrl
          __typename
        }
        mergeRequest {
          id
          title
          mergedAt
          webUrl
          author {
            id
            name
            username
            avatarUrl
            webUrl
            __typename
          }
          mergeUser {
            id
            name
            username
            avatarUrl
            webUrl
            __typename
          }
          committers {
            nodes {
              id
              name
              username
              avatarUrl
              webUrl
              __typename
            }
            __typename
          }
          participants {
            nodes {
              id
              name
              username
              avatarUrl
              webUrl
              __typename
            }
            __typename
          }
          approvedBy {
            nodes {
              id
              name
              username
              avatarUrl
              webUrl
              __typename
            }
            __typename
          }
          ref: reference
          fullRef: reference(full: true)
          sourceBranch
          sourceBranchExists
          targetBranch
          targetBranchExists
          project {
            id
            avatarUrl
            name
            webUrl
            complianceFrameworks {
              nodes {
                id
                name
                description
                color
                __typename
              }
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      pageInfo {
        ...PageInfo
        __typename
      }
      __typename
    }
    __typename
  }
}

fragment PageInfo on PageInfo {
  hasNextPage
  hasPreviousPage
  startCursor
  endCursor
  __typename
}

Screenshots or screen recordings

Sort option Page 1 Page 2 Cursor value example
Severity level gdk.localhost_3443_groups_gitlab-org_-_security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__2 eyJzZXZlcml0eV9sZXZlbCI6ImhpZ2giLCJpZCI6IjU4OSJ9
{"severity_level"=>"high", "id"=>"589"}
Violation reason gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__3 gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__4 eyJyZWFzb24iOiJhcHByb3ZlZF9ieV9pbnN1ZmZpY2llbnRfdXNlcnMiLCJpZCI6IjI0In0
{"reason"=>"approved_by_insufficient_users", "id"=>"24"}
MR title gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__5 gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__6 NDA
40
Date merged gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__7 gdk.localhost_3443_groups_gitlab-org_-security_compliance_dashboard_mergedAfter_2022-02-19_mergedBefore_2022-03-21_sort_MERGED_AT_ASC__8 NDA
40

How to set up and validate locally

Setting up the violations

  1. Have a GitLab Ultimate license.
  2. Checkout the branch from this MR.
  3. Follow the setup steps in the MR above.

Running the query

  1. Open your preferred GraphQL caller. You could use [GDK_HOST]/-/graphql-explorer
  2. Check that the violations you created above are shown using the query
  3. Test the different sorts to check that they work as expected

You can check the cursor contents by running the below in rails c:

cursor = "CURSOR_VALUE"
json = Base64Bp.urlsafe_decode64(cursor)
Gitlab::Json.parse(json)

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #356408 (closed)

Edited by Robert Hunt

Merge request reports