Skip to the content.

Home

Previous: Chapter 13 - The Filter


📝 As an app user, I want to archive a user, so that they are removed from the selection process.

We’re finally ready to give clients the ability to modify a user’s archived status. We already know exactly what we’ll need.

Generate a new mutation.

Terminal

bin/rails g graphql:mutation UserArchive

Sort the mutations.

app/graphql/types/mutation_type.rb

module Types
  class MutationType < Types::BaseObject
    field :round_create, mutation: Mutations::RoundCreate
    field :selection_create, mutation: Mutations::SelectionCreate
    field :selection_delete, mutation: Mutations::SelectionDelete
    field :user_archive, mutation: Mutations::UserArchive
    field :user_create, mutation: Mutations::UserCreate
  end
end

Since we used a more generic generator, we’ll have to fill in a lot more by hand this time. Luckily we have plenty of examples to draw from.

Fill in the new mutation.

app/graphql/mutations/user_archive.rb

module Mutations
  class UserArchive < BaseMutation
    description "Archives or unarchives a user by ID"

    field :user, Types::UserType, null: false

    argument :id, ID, required: true

    def resolve(id:)
      user = User.find(id)
      user.toggle!(:archived)
      { user: user }
    end
  end
end

Generate a test for the mutation.

Terminal

bin/rails g integration_test types/mutation_type/user_archive

Fill in the generated test.

test/integration/types/mutation_type/user_archive_test.rb

require "test_helper"

class Types::MutationType::UserArchiveTest < ActionDispatch::IntegrationTest
  setup do
    @query = <<~GRAPHQL
      mutation UserArchive($id: ID!) {
        userArchive(input: { id: $id }) {
          user {
            id
            name
            email
            createdAt
            updatedAt
            archived
          }
        }
      }
    GRAPHQL
  end

  test "user_archive" do
    user = users(:daniel)
    variables = { id: user.id }

    assert_changes -> { user.archived }, from: false, to: true do
      post graphql_path, params: { query: @query, variables: variables }

      user.reload

      assert_equal(
        {
          "data" => {
            "userArchive" => {
              "user" => {
                "id" => user.id.to_s,
                "name" => user.name,
                "email" => user.email,
                "createdAt" => user.created_at.iso8601,
                "updatedAt" => user.updated_at.iso8601,
                "archived" => user.archived,
              },
            },
          },
        },
        @response.parsed_body
      )
    end
  end

  test "user_archive when archived" do
    user = users(:casper)
    variables = { id: user.id }

    assert_changes -> { user.archived }, from: true, to: false do
      post graphql_path, params: { query: @query, variables: variables }

      user.reload

      assert_equal(
        {
          "data" => {
            "userArchive" => {
              "user" => {
                "id" => user.id.to_s,
                "name" => user.name,
                "email" => user.email,
                "createdAt" => user.created_at.iso8601,
                "updatedAt" => user.updated_at.iso8601,
                "archived" => user.archived,
              },
            },
          },
        },
        @response.parsed_body
      )
    end
  end
end

Run the test.

Terminal

bin/rails t test/integration/types/mutation_type/user_archive_test.rb

Check for regressions by running all tests.

Terminal

bin/rails t

Success!

✅ Make a commit

✅ As an app user, I want to archive a user, so that they are removed from the selection process.


Next: Chapter 15 - The Index