diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
new file mode 100644
index 0000000000000000000000000000000000000000..a59a8afa4de964b72700f11794b8e904d521b682
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
@@ -0,0 +1,304 @@
+<script>
+import {
+  GlIcon,
+  GlLink,
+  GlForm,
+  GlFormInputGroup,
+  GlInputGroupText,
+  GlFormInput,
+  GlFormGroup,
+  GlFormTextarea,
+  GlButton,
+  GlFormRadio,
+  GlFormRadioGroup,
+  GlFormSelect,
+} from '@gitlab/ui';
+import { buildApiUrl } from '~/api/api_utils';
+import createFlash from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import csrf from '~/lib/utils/csrf';
+import { redirectTo } from '~/lib/utils/url_utility';
+import { s__ } from '~/locale';
+
+const PRIVATE_VISIBILITY = 'private';
+const INTERNAL_VISIBILITY = 'internal';
+const PUBLIC_VISIBILITY = 'public';
+
+const ALLOWED_VISIBILITY = {
+  private: [PRIVATE_VISIBILITY],
+  internal: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY],
+  public: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY, PUBLIC_VISIBILITY],
+};
+
+export default {
+  components: {
+    GlForm,
+    GlIcon,
+    GlLink,
+    GlButton,
+    GlFormInputGroup,
+    GlInputGroupText,
+    GlFormInput,
+    GlFormTextarea,
+    GlFormGroup,
+    GlFormRadio,
+    GlFormRadioGroup,
+    GlFormSelect,
+  },
+  props: {
+    endpoint: {
+      type: String,
+      required: true,
+    },
+    newGroupPath: {
+      type: String,
+      required: true,
+    },
+    projectFullPath: {
+      type: String,
+      required: true,
+    },
+    visibilityHelpPath: {
+      type: String,
+      required: true,
+    },
+    projectId: {
+      type: String,
+      required: true,
+    },
+    projectName: {
+      type: String,
+      required: true,
+    },
+    projectPath: {
+      type: String,
+      required: true,
+    },
+    projectDescription: {
+      type: String,
+      required: true,
+    },
+    projectVisibility: {
+      type: String,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      isSaving: false,
+      namespaces: [],
+      selectedNamespace: {},
+      fork: {
+        name: this.projectName,
+        slug: this.projectPath,
+        description: this.projectDescription,
+        visibility: this.projectVisibility,
+      },
+    };
+  },
+  computed: {
+    projectUrl() {
+      return `${gon.gitlab_url}/`;
+    },
+    projectAllowedVisibility() {
+      return ALLOWED_VISIBILITY[this.projectVisibility];
+    },
+    namespaceAllowedVisibility() {
+      return (
+        ALLOWED_VISIBILITY[this.selectedNamespace.visibility] ||
+        ALLOWED_VISIBILITY[PUBLIC_VISIBILITY]
+      );
+    },
+    visibilityLevels() {
+      return [
+        {
+          text: s__('ForkProject|Private'),
+          value: PRIVATE_VISIBILITY,
+          icon: 'lock',
+          help: s__('ForkProject|The project can be accessed without any authentication.'),
+          disabled: this.isVisibilityLevelDisabled(PRIVATE_VISIBILITY),
+        },
+        {
+          text: s__('ForkProject|Internal'),
+          value: INTERNAL_VISIBILITY,
+          icon: 'shield',
+          help: s__('ForkProject|The project can be accessed by any logged in user.'),
+          disabled: this.isVisibilityLevelDisabled(INTERNAL_VISIBILITY),
+        },
+        {
+          text: s__('ForkProject|Public'),
+          value: PUBLIC_VISIBILITY,
+          icon: 'earth',
+          help: s__(
+            'ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.',
+          ),
+          disabled: this.isVisibilityLevelDisabled(PUBLIC_VISIBILITY),
+        },
+      ];
+    },
+  },
+  watch: {
+    selectedNamespace(newVal) {
+      const { visibility } = newVal;
+
+      if (this.projectAllowedVisibility.includes(visibility)) {
+        this.fork.visibility = visibility;
+      }
+    },
+  },
+  mounted() {
+    this.fetchNamespaces();
+  },
+  methods: {
+    async fetchNamespaces() {
+      const { data } = await axios.get(this.endpoint);
+      this.namespaces = data.namespaces;
+    },
+    isVisibilityLevelDisabled(visibilityLevel) {
+      return !(
+        this.projectAllowedVisibility.includes(visibilityLevel) &&
+        this.namespaceAllowedVisibility.includes(visibilityLevel)
+      );
+    },
+    async onSubmit() {
+      this.isSaving = true;
+
+      const { projectId } = this;
+      const { name, slug, description, visibility } = this.fork;
+      const { id: namespaceId } = this.selectedNamespace;
+
+      const postParams = {
+        id: projectId,
+        name,
+        namespace_id: namespaceId,
+        path: slug,
+        description,
+        visibility,
+      };
+
+      const forkProjectPath = `/api/:version/projects/:id/fork`;
+      const url = buildApiUrl(forkProjectPath).replace(':id', encodeURIComponent(this.projectId));
+
+      try {
+        const { data } = await axios.post(url, postParams);
+        redirectTo(data.web_url);
+        return;
+      } catch (error) {
+        createFlash({ message: error });
+      }
+    },
+  },
+  csrf,
+};
+</script>
+
+<template>
+  <gl-form method="POST" @submit.prevent="onSubmit">
+    <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
+
+    <gl-form-group label="Project name" label-for="fork-name">
+      <gl-form-input id="fork-name" v-model="fork.name" data-testid="fork-name-input" required />
+    </gl-form-group>
+
+    <div class="gl-display-flex">
+      <div class="gl-w-half">
+        <gl-form-group label="Project URL" label-for="fork-url" class="gl-pr-2">
+          <gl-form-input-group>
+            <template #prepend>
+              <gl-input-group-text>
+                {{ projectUrl }}
+              </gl-input-group-text>
+            </template>
+            <gl-form-select
+              id="fork-url"
+              v-model="selectedNamespace"
+              data-testid="fork-url-input"
+              required
+            >
+              <template slot="first">
+                <option :value="null" disabled>{{ s__('ForkProject|Select a namespace') }}</option>
+              </template>
+              <option v-for="namespace in namespaces" :key="namespace.id" :value="namespace">
+                {{ namespace.name }}
+              </option>
+            </gl-form-select>
+          </gl-form-input-group>
+        </gl-form-group>
+      </div>
+      <div class="gl-w-half">
+        <gl-form-group label="Project slug" label-for="fork-slug" class="gl-pl-2">
+          <gl-form-input
+            id="fork-slug"
+            v-model="fork.slug"
+            data-testid="fork-slug-input"
+            required
+          />
+        </gl-form-group>
+      </div>
+    </div>
+
+    <p class="gl-mt-n5 gl-text-gray-500">
+      {{ s__('ForkProject|Want to house several dependent projects under the same namespace?') }}
+      <gl-link :href="newGroupPath" target="_blank">
+        {{ s__('ForkProject|Create a group') }}
+      </gl-link>
+    </p>
+
+    <gl-form-group label="Project description (optional)" label-for="fork-description">
+      <gl-form-textarea
+        id="fork-description"
+        v-model="fork.description"
+        data-testid="fork-description-textarea"
+      />
+    </gl-form-group>
+
+    <gl-form-group>
+      <label>
+        {{ s__('ForkProject|Visibility level') }}
+        <gl-link :href="visibilityHelpPath" target="_blank">
+          <gl-icon name="question-o" />
+        </gl-link>
+      </label>
+      <gl-form-radio-group
+        v-model="fork.visibility"
+        data-testid="fork-visibility-radio-group"
+        required
+      >
+        <gl-form-radio
+          v-for="{ text, value, icon, help, disabled } in visibilityLevels"
+          :key="value"
+          :value="value"
+          :disabled="disabled"
+          :data-testid="`radio-${value}`"
+        >
+          <div>
+            <gl-icon :name="icon" />
+            <span>{{ text }}</span>
+          </div>
+          <template #help>{{ help }}</template>
+        </gl-form-radio>
+      </gl-form-radio-group>
+    </gl-form-group>
+
+    <div class="gl-display-flex gl-justify-content-space-between gl-mt-8">
+      <gl-button
+        type="submit"
+        category="primary"
+        variant="confirm"
+        data-testid="submit-button"
+        :loading="isSaving"
+      >
+        {{ s__('ForkProject|Fork project') }}
+      </gl-button>
+      <gl-button
+        type="reset"
+        class="gl-mr-3"
+        data-testid="cancel-button"
+        :disabled="isSaving"
+        :href="projectFullPath"
+      >
+        {{ s__('ForkProject|Cancel') }}
+      </gl-button>
+    </div>
+  </gl-form>
+</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
index 26353aefe828cd0bdad272208f0aeb5cb33a28af..420639eefb7af6a779fdc2dcba27e190ce21dfc9 100644
--- a/app/assets/javascripts/pages/projects/forks/new/index.js
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -1,16 +1,53 @@
 import Vue from 'vue';
+import ForkForm from './components/fork_form.vue';
 import ForkGroupsList from './components/fork_groups_list.vue';
 
 const mountElement = document.getElementById('fork-groups-mount-element');
-const { endpoint } = mountElement.dataset;
-// eslint-disable-next-line no-new
-new Vue({
-  el: mountElement,
-  render(h) {
-    return h(ForkGroupsList, {
-      props: {
-        endpoint,
-      },
-    });
-  },
-});
+
+if (gon.features.forkProjectForm) {
+  const {
+    endpoint,
+    newGroupPath,
+    projectFullPath,
+    visibilityHelpPath,
+    projectId,
+    projectName,
+    projectPath,
+    projectDescription,
+    projectVisibility,
+  } = mountElement.dataset;
+
+  // eslint-disable-next-line no-new
+  new Vue({
+    el: mountElement,
+    render(h) {
+      return h(ForkForm, {
+        props: {
+          endpoint,
+          newGroupPath,
+          projectFullPath,
+          visibilityHelpPath,
+          projectId,
+          projectName,
+          projectPath,
+          projectDescription,
+          projectVisibility,
+        },
+      });
+    },
+  });
+} else {
+  const { endpoint } = mountElement.dataset;
+
+  // eslint-disable-next-line no-new
+  new Vue({
+    el: mountElement,
+    render(h) {
+      return h(ForkGroupsList, {
+        props: {
+          endpoint,
+        },
+      });
+    },
+  });
+}
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index 5576d5766c790584591d23db73607510e3b1e02a..33f046f414f1c05cbae79f80ab6147a225a8edeb 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -16,6 +16,10 @@ class Projects::ForksController < Projects::ApplicationController
 
   feature_category :source_code_management
 
+  before_action do
+    push_frontend_feature_flag(:fork_project_form)
+  end
+
   def index
     @total_forks_count    = project.forks.size
     @public_forks_count   = project.forks.public_only.size
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index ccef28a2cf3050cf30a78c19aef7ced03525649b..562aa0fd353d7c8e7a7f93a9eb4eb77d44b1dce4 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -9,10 +9,20 @@
       %br
       = _('Forking a repository allows you to make changes without affecting the original project.')
   .col-lg-9
-    - if @own_namespace.present?
-      .fork-thumbnail-container.js-fork-content
-        %h5.gl-mt-0.gl-mb-0.gl-ml-3.gl-mr-3
-          = _("Select a namespace to fork the project")
-        = render 'fork_button', namespace: @own_namespace
-    #fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json) } }
-
+    - if Feature.enabled?(:fork_project_form)
+      #fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json),
+        new_group_path: new_group_path,
+        project_full_path: project_path(@project),
+        visibility_help_path: help_page_path("public_access/public_access"),
+        project_id: @project.id,
+        project_name: @project.name,
+        project_path: @project.path,
+        project_description: @project.description,
+        project_visibility: @project.visibility } }
+    - else
+      - if @own_namespace.present?
+        .fork-thumbnail-container.js-fork-content
+          %h5.gl-mt-0.gl-mb-0.gl-ml-3.gl-mr-3
+            = _("Select a namespace to fork the project")
+          = render 'fork_button', namespace: @own_namespace
+      #fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json) } }
diff --git a/config/feature_flags/development/fork_project_form.yml b/config/feature_flags/development/fork_project_form.yml
new file mode 100644
index 0000000000000000000000000000000000000000..93bccc4f41bbb675423265d13f82c51460eedd5f
--- /dev/null
+++ b/config/feature_flags/development/fork_project_form.yml
@@ -0,0 +1,8 @@
+---
+name: fork_project_form
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53544
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321387
+milestone: '13.10'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index bc98ce39dd72eac28d0026857b0bd2b9ae5610bb..8fc237e07eb5206a4160e077d4a657afe83b051b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -13262,6 +13262,42 @@ msgstr ""
 msgid "Fork project?"
 msgstr ""
 
+msgid "ForkProject|Cancel"
+msgstr ""
+
+msgid "ForkProject|Create a group"
+msgstr ""
+
+msgid "ForkProject|Fork project"
+msgstr ""
+
+msgid "ForkProject|Internal"
+msgstr ""
+
+msgid "ForkProject|Private"
+msgstr ""
+
+msgid "ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group."
+msgstr ""
+
+msgid "ForkProject|Public"
+msgstr ""
+
+msgid "ForkProject|Select a namespace"
+msgstr ""
+
+msgid "ForkProject|The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "ForkProject|The project can be accessed without any authentication."
+msgstr ""
+
+msgid "ForkProject|Visibility level"
+msgstr ""
+
+msgid "ForkProject|Want to house several dependent projects under the same namespace?"
+msgstr ""
+
 msgid "ForkedFromProjectPath|Forked from"
 msgstr ""
 
diff --git a/spec/features/projects/fork_spec.rb b/spec/features/projects/fork_spec.rb
index 8d0500f5e1353357c7bbe1c32f8917cf0501f4dc..59bed5501f227b09c4dbcc82c4289399831a2b8e 100644
--- a/spec/features/projects/fork_spec.rb
+++ b/spec/features/projects/fork_spec.rb
@@ -9,6 +9,7 @@
   let(:project) { create(:project, :public, :repository) }
 
   before do
+    stub_feature_flags(fork_project_form: false)
     sign_in(user)
   end
 
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..5aafb1e8d2ec0675650f07b5030dddc662ad7d14
--- /dev/null
+++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
@@ -0,0 +1,273 @@
+import { GlForm, GlFormInputGroup } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import axios from 'axios';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import createFlash from '~/flash';
+import httpStatus from '~/lib/utils/http_status';
+import * as urlUtility from '~/lib/utils/url_utility';
+import ForkForm from '~/pages/projects/forks/new/components/fork_form.vue';
+
+jest.mock('~/flash');
+jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
+
+describe('ForkForm component', () => {
+  let wrapper;
+  let axiosMock;
+
+  const GON_GITLAB_URL = 'https://gitlab.com';
+  const GON_API_VERSION = 'v7';
+
+  const MOCK_NAMESPACES_RESPONSE = [
+    {
+      name: 'one',
+      id: 1,
+    },
+    {
+      name: 'two',
+      id: 2,
+    },
+  ];
+
+  const DEFAULT_PROPS = {
+    endpoint: '/some/project-full-path/-/forks/new.json',
+    newGroupPath: 'some/groups/path',
+    projectFullPath: '/some/project-full-path',
+    visibilityHelpPath: 'some/visibility/help/path',
+    projectId: '10',
+    projectName: 'Project Name',
+    projectPath: 'project-name',
+    projectDescription: 'some project description',
+    projectVisibility: 'private',
+  };
+
+  const mockGetRequest = (data = {}, statusCode = httpStatus.OK) => {
+    axiosMock.onGet(DEFAULT_PROPS.endpoint).replyOnce(statusCode, data);
+  };
+
+  const createComponent = (props = {}, data = {}) => {
+    wrapper = shallowMount(ForkForm, {
+      propsData: {
+        ...DEFAULT_PROPS,
+        ...props,
+      },
+      data() {
+        return {
+          ...data,
+        };
+      },
+      stubs: {
+        GlFormInputGroup,
+      },
+    });
+  };
+
+  beforeEach(() => {
+    axiosMock = new AxiosMockAdapter(axios);
+    window.gon = {
+      gitlab_url: GON_GITLAB_URL,
+      api_version: GON_API_VERSION,
+    };
+  });
+
+  afterEach(() => {
+    wrapper.destroy();
+    axiosMock.restore();
+  });
+
+  const findPrivateRadio = () => wrapper.find('[data-testid="radio-private"]');
+  const findInternalRadio = () => wrapper.find('[data-testid="radio-internal"]');
+  const findPublicRadio = () => wrapper.find('[data-testid="radio-public"]');
+  const findForkNameInput = () => wrapper.find('[data-testid="fork-name-input"]');
+  const findForkUrlInput = () => wrapper.find('[data-testid="fork-url-input"]');
+  const findForkSlugInput = () => wrapper.find('[data-testid="fork-slug-input"]');
+  const findForkDescriptionTextarea = () =>
+    wrapper.find('[data-testid="fork-description-textarea"]');
+  const findVisibilityRadioGroup = () =>
+    wrapper.find('[data-testid="fork-visibility-radio-group"]');
+
+  it('will go to projectFullPath when click cancel button', () => {
+    mockGetRequest();
+    createComponent();
+
+    const { projectFullPath } = DEFAULT_PROPS;
+    const cancelButton = wrapper.find('[data-testid="cancel-button"]');
+
+    expect(cancelButton.attributes('href')).toBe(projectFullPath);
+  });
+
+  it('make POST request with project param', async () => {
+    jest.spyOn(axios, 'post');
+
+    const namespaceId = 20;
+
+    mockGetRequest();
+    createComponent(
+      {},
+      {
+        selectedNamespace: {
+          id: namespaceId,
+        },
+      },
+    );
+
+    wrapper.find(GlForm).vm.$emit('submit', { preventDefault: () => {} });
+
+    const {
+      projectId,
+      projectDescription,
+      projectName,
+      projectPath,
+      projectVisibility,
+    } = DEFAULT_PROPS;
+
+    const url = `/api/${GON_API_VERSION}/projects/${projectId}/fork`;
+    const project = {
+      description: projectDescription,
+      id: projectId,
+      name: projectName,
+      namespace_id: namespaceId,
+      path: projectPath,
+      visibility: projectVisibility,
+    };
+
+    expect(axios.post).toHaveBeenCalledWith(url, project);
+  });
+
+  it('has input with csrf token', () => {
+    mockGetRequest();
+    createComponent();
+
+    expect(wrapper.find('input[name="authenticity_token"]').attributes('value')).toBe(
+      'mock-csrf-token',
+    );
+  });
+
+  it('pre-populate form from project props', () => {
+    mockGetRequest();
+    createComponent();
+
+    expect(findForkNameInput().attributes('value')).toBe(DEFAULT_PROPS.projectName);
+    expect(findForkSlugInput().attributes('value')).toBe(DEFAULT_PROPS.projectPath);
+    expect(findForkDescriptionTextarea().attributes('value')).toBe(
+      DEFAULT_PROPS.projectDescription,
+    );
+  });
+
+  it('sets project URL prepend text with gon.gitlab_url', () => {
+    mockGetRequest();
+    createComponent();
+
+    expect(wrapper.find(GlFormInputGroup).text()).toContain(`${GON_GITLAB_URL}/`);
+  });
+
+  it('will have required attribute for required fields', () => {
+    mockGetRequest();
+    createComponent();
+
+    expect(findForkNameInput().attributes('required')).not.toBeUndefined();
+    expect(findForkUrlInput().attributes('required')).not.toBeUndefined();
+    expect(findForkSlugInput().attributes('required')).not.toBeUndefined();
+    expect(findVisibilityRadioGroup().attributes('required')).not.toBeUndefined();
+    expect(findForkDescriptionTextarea().attributes('required')).toBeUndefined();
+  });
+
+  describe('forks namespaces', () => {
+    beforeEach(() => {
+      mockGetRequest({ namespaces: MOCK_NAMESPACES_RESPONSE });
+      createComponent();
+    });
+
+    it('make GET request from endpoint', async () => {
+      await axios.waitForAll();
+
+      expect(axiosMock.history.get[0].url).toBe(DEFAULT_PROPS.endpoint);
+    });
+
+    it('generate default option', async () => {
+      await axios.waitForAll();
+
+      const optionsArray = findForkUrlInput().findAll('option');
+
+      expect(optionsArray.at(0).text()).toBe('Select a namespace');
+    });
+
+    it('populate project url namespace options', async () => {
+      await axios.waitForAll();
+
+      const optionsArray = findForkUrlInput().findAll('option');
+
+      expect(optionsArray).toHaveLength(MOCK_NAMESPACES_RESPONSE.length + 1);
+      expect(optionsArray.at(1).text()).toBe(MOCK_NAMESPACES_RESPONSE[0].name);
+      expect(optionsArray.at(2).text()).toBe(MOCK_NAMESPACES_RESPONSE[1].name);
+    });
+  });
+
+  describe('visibility level', () => {
+    it.each`
+      project       | namespace     | privateIsDisabled | internalIsDisabled | publicIsDisabled
+      ${'private'}  | ${'private'}  | ${undefined}      | ${'true'}          | ${'true'}
+      ${'private'}  | ${'internal'} | ${undefined}      | ${'true'}          | ${'true'}
+      ${'private'}  | ${'public'}   | ${undefined}      | ${'true'}          | ${'true'}
+      ${'internal'} | ${'private'}  | ${undefined}      | ${'true'}          | ${'true'}
+      ${'internal'} | ${'internal'} | ${undefined}      | ${undefined}       | ${'true'}
+      ${'internal'} | ${'public'}   | ${undefined}      | ${undefined}       | ${'true'}
+      ${'public'}   | ${'private'}  | ${undefined}      | ${'true'}          | ${'true'}
+      ${'public'}   | ${'internal'} | ${undefined}      | ${undefined}       | ${'true'}
+      ${'public'}   | ${'public'}   | ${undefined}      | ${undefined}       | ${undefined}
+    `(
+      'sets appropriate radio button disabled state',
+      async ({ project, namespace, privateIsDisabled, internalIsDisabled, publicIsDisabled }) => {
+        mockGetRequest();
+        createComponent(
+          {
+            projectVisibility: project,
+          },
+          {
+            selectedNamespace: {
+              visibility: namespace,
+            },
+          },
+        );
+
+        expect(findPrivateRadio().attributes('disabled')).toBe(privateIsDisabled);
+        expect(findInternalRadio().attributes('disabled')).toBe(internalIsDisabled);
+        expect(findPublicRadio().attributes('disabled')).toBe(publicIsDisabled);
+      },
+    );
+  });
+
+  describe('onSubmit', () => {
+    beforeEach(() => {
+      jest.spyOn(urlUtility, 'redirectTo').mockImplementation();
+    });
+
+    it('redirect to POST web_url response', async () => {
+      const webUrl = `new/fork-project`;
+
+      jest.spyOn(axios, 'post').mockResolvedValue({ data: { web_url: webUrl } });
+
+      mockGetRequest();
+      createComponent();
+
+      await wrapper.vm.onSubmit();
+
+      expect(urlUtility.redirectTo).toHaveBeenCalledWith(webUrl);
+    });
+
+    it('display flash when POST is unsuccessful', async () => {
+      const dummyError = 'Fork project failed';
+
+      jest.spyOn(axios, 'post').mockRejectedValue(dummyError);
+
+      mockGetRequest();
+      createComponent();
+
+      await wrapper.vm.onSubmit();
+
+      expect(urlUtility.redirectTo).not.toHaveBeenCalled();
+      expect(createFlash).toHaveBeenCalledWith({
+        message: dummyError,
+      });
+    });
+  });
+});