fork.feature 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9
Feature: hub fork
  Background:
    Given I am in "dotfiles" git repo
    And the "origin" remote has url "git://github.com/evilchelu/dotfiles.git"
    And I am "mislav" on github.com with OAuth token "OTOKEN"

  Scenario: Fork the repository
    Given the GitHub API server:
      """
10 11 12 13
      before {
        halt 400 unless request.env['HTTP_X_ORIGINAL_SCHEME'] == 'https'
        halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
      }
J
Jingwen Owen Ou 已提交
14
      get('/repos/mislav/dotfiles', :host_name => 'api.github.com') { 404 }
15
      post('/repos/evilchelu/dotfiles/forks', :host_name => 'api.github.com') {
16
        assert :organization => nil
17 18 19
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
20 21 22
      """
    When I successfully run `hub fork`
    Then the output should contain exactly "new remote: mislav\n"
23 24
    And "git remote add -f mislav git://github.com/evilchelu/dotfiles.git" should be run
    And "git remote set-url mislav git@github.com:mislav/dotfiles.git" should be run
25 26
    And the url for "mislav" should be "git@github.com:mislav/dotfiles.git"

27 28 29
  Scenario: Fork the repository with new remote name specified
    Given the GitHub API server:
      """
M
Marc Abramowitz 已提交
30 31
      get('/repos/mislav/dotfiles') { 404 }
      post('/repos/evilchelu/dotfiles/forks') {
32 33 34 35 36 37
        assert :organization => nil
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
      """
    When I successfully run `hub fork --remote-name=origin`
38 39 40 41 42
    Then the output should contain exactly:
      """
      renaming existing "origin" remote to "upstream"
      new remote: origin\n
      """
43 44 45
    And "git remote add -f origin git://github.com/evilchelu/dotfiles.git" should be run
    And "git remote set-url origin git@github.com:mislav/dotfiles.git" should be run
    And the url for "origin" should be "git@github.com:mislav/dotfiles.git"
46
    And the url for "upstream" should be "git://github.com/evilchelu/dotfiles.git"
47

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
  Scenario: Fork the repository with redirect
    Given the GitHub API server:
      """
      before {
        halt 400 unless request.env['HTTP_X_ORIGINAL_SCHEME'] == 'https'
        halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
      }
      get('/repos/mislav/dotfiles', :host_name => 'api.github.com') { 404 }
      post('/repos/evilchelu/dotfiles/forks', :host_name => 'api.github.com') {
        redirect 'https://api.github.com/repositories/1234/forks', 307
      }
      post('/repositories/1234/forks', :host_name => 'api.github.com') {
        status 202
        json :name => 'my-dotfiles', :owner => { :login => 'MiSlAv' }
      }
      """
    When I successfully run `hub fork`
    Then the output should contain exactly "new remote: mislav\n"
    And "git remote add -f mislav git://github.com/evilchelu/dotfiles.git" should be run
    And "git remote set-url mislav git@github.com:MiSlAv/my-dotfiles.git" should be run
    And the url for "mislav" should be "git@github.com:MiSlAv/my-dotfiles.git"

70 71 72 73 74
  Scenario: Fork the repository when origin URL is private
    Given the "origin" remote has url "git@github.com:evilchelu/dotfiles.git"
    Given the GitHub API server:
      """
      before { halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' }
75
      get('/repos/mislav/dotfiles', :host_name => 'api.github.com') { 404 }
76 77 78 79
      post('/repos/evilchelu/dotfiles/forks', :host_name => 'api.github.com') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
80 81 82 83 84 85 86
      """
    When I successfully run `hub fork`
    Then the output should contain exactly "new remote: mislav\n"
    And "git remote add -f mislav ssh://git@github.com/evilchelu/dotfiles.git" should be run
    And "git remote set-url mislav git@github.com:mislav/dotfiles.git" should be run
    And the url for "mislav" should be "git@github.com:mislav/dotfiles.git"

87 88 89
  Scenario: --no-remote
    Given the GitHub API server:
      """
90 91 92 93
      post('/repos/evilchelu/dotfiles/forks') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
      """
    When I successfully run `hub fork --no-remote`
    Then there should be no output
    And there should be no "mislav" remote

  Scenario: Fork failed
    Given the GitHub API server:
      """
      post('/repos/evilchelu/dotfiles/forks') { halt 500 }
      """
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain exactly:
      """
      Error creating fork: Internal Server Error (HTTP 500)\n
      """
    And there should be no "mislav" remote

112
  Scenario: Unrelated fork already exists
113 114
    Given the GitHub API server:
      """
115
      get('/repos/mislav/dotfiles') {
116
        halt 406 unless request.env['HTTP_ACCEPT'] == 'application/vnd.github.v3+json;charset=utf-8'
117 118
        json :html_url => 'https://github.com/mislav/dotfiles',
             :parent => { :html_url => 'https://github.com/unrelated/dotfiles' }
119
      }
120 121 122 123 124
      """
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain exactly:
      """
125
      Error creating fork: mislav/dotfiles already exists on github.com\n
126 127 128
      """
    And there should be no "mislav" remote

E
Elliott Beach 已提交
129
  Scenario: Related fork already exists
130 131
    Given the GitHub API server:
      """
132
      get('/repos/mislav/dotfiles') {
133 134
        json :html_url => 'https://github.com/mislav/dotfiles',
             :parent => { :html_url => 'https://github.com/EvilChelu/Dotfiles' }
135
      }
136 137 138
      """
    When I run `hub fork`
    Then the exit status should be 0
139 140 141 142
    Then the stdout should contain exactly:
      """
      new remote: mislav\n
      """
143 144
    And the url for "mislav" should be "git@github.com:mislav/dotfiles.git"

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
  Scenario: Redirected repo already exists
    Given the GitHub API server:
      """
      get('/repos/mislav/dotfiles') {
        redirect 'https://api.github.com/repositories/12345', 301
      }
      get('/repositories/12345') {
        json :html_url => 'https://github.com/mislav/old-dotfiles'
      }
      post('/repos/evilchelu/dotfiles/forks') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
      """
    When I successfully run `hub fork`
    And the stdout should contain exactly "new remote: mislav\n"
E
Elliott Beach 已提交
161

E
Elliott Beach 已提交
162
  Scenario: Unrelated remote already exists
E
Elliott Beach 已提交
163 164 165
    Given the "mislav" remote has url "git@github.com:mislav/unrelated.git"
    Given the GitHub API server:
      """
E
Elliott Beach 已提交
166 167 168 169 170 171
      get('/repos/mislav/dotfiles', :host_name => 'api.github.com') { 404 }
      post('/repos/evilchelu/dotfiles/forks', :host_name => 'api.github.com') {
        assert :organization => nil
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
E
Elliott Beach 已提交
172 173 174 175 176 177 178 179 180
      """
    When I run `hub fork`
    Then the exit status should be 128
    And the stderr should contain exactly:
      """
      fatal: remote mislav already exists.\n
      """
    And the url for "mislav" should be "git@github.com:mislav/unrelated.git"

E
Elliott Beach 已提交
181 182 183 184 185
  Scenario: Related fork and related remote already exist
    Given the "mislav" remote has url "git@github.com:mislav/dotfiles.git"
    Given the GitHub API server:
      """
      get('/repos/mislav/dotfiles') {
186 187
        json :html_url => 'https://github.com/mislav/dotfiles',
             :parent => { :html_url => 'https://github.com/EvilChelu/Dotfiles' }
E
Elliott Beach 已提交
188 189 190 191 192 193 194 195 196
      }
      """
    When I run `hub fork`
    Then the exit status should be 0
    And the stdout should contain exactly:
      """
      existing remote: mislav\n
      """
    And the url for "mislav" should be "git@github.com:mislav/dotfiles.git"
197

E
Elliott Beach 已提交
198
  Scenario: Related fork and related remote, but with differing protocol, already exist
E
Elliott Beach 已提交
199 200
    Given the "mislav" remote has url "https://github.com/mislav/dotfiles.git"
    Given the GitHub API server:
E
Elliott Beach 已提交
201
      """
202
      get('/repos/mislav/dotfiles') {
203 204
        json :html_url => 'https://github.com/mislav/dotfiles',
             :parent => { :html_url => 'https://github.com/EvilChelu/Dotfiles' }
205
      }
E
Elliott Beach 已提交
206
      """
E
Elliott Beach 已提交
207 208
    When I run `hub fork`
    Then the exit status should be 0
209 210 211 212 213
    And the stdout should contain exactly:
      """
      existing remote: mislav\n
      """
    And the url for "mislav" should be "https://github.com/mislav/dotfiles.git"
214

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  Scenario: Invalid OAuth token
    Given the GitHub API server:
      """
      before { halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' }
      """
    And I am "mislav" on github.com with OAuth token "WRONGTOKEN"
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain exactly:
      """
      Error creating fork: Unauthorized (HTTP 401)\n
      """

  Scenario: HTTPS is preferred
    Given the GitHub API server:
      """
231 232 233 234
      post('/repos/evilchelu/dotfiles/forks') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
235 236 237 238 239 240 241 242 243 244 245 246
      """
    And HTTPS is preferred
    When I successfully run `hub fork`
    Then the output should contain exactly "new remote: mislav\n"
    And the url for "mislav" should be "https://github.com/mislav/dotfiles.git"

  Scenario: Not in repo
    Given the current dir is not a repo
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain "fatal: Not a git repository"

247
  Scenario: Origin remote doesn't exist
248
    Given I run `git remote rm origin`
249 250 251 252
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain exactly:
      """
253
      Aborted: the origin remote doesn't point to a GitHub repository.\n
254 255 256
      """
    And there should be no "origin" remote

257 258 259 260 261 262
  Scenario: Unknown host
    Given the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git"
    When I run `hub fork`
    Then the exit status should be 1
    And the stderr should contain exactly:
      """
263
      Aborted: the origin remote doesn't point to a GitHub repository.\n
264 265 266 267 268
      """

  Scenario: Enterprise fork
    Given the GitHub API server:
      """
269 270 271 272
      before {
        halt 400 unless request.env['HTTP_X_ORIGINAL_SCHEME'] == 'https'
        halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token FITOKEN'
      }
273 274 275 276
      post('/api/v3/repos/evilchelu/dotfiles/forks', :host_name => 'git.my.org') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
277 278 279 280 281 282
      """
    And the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git"
    And I am "mislav" on git.my.org with OAuth token "FITOKEN"
    And "git.my.org" is a whitelisted Enterprise host
    When I successfully run `hub fork`
    Then the url for "mislav" should be "git@git.my.org:mislav/dotfiles.git"
283 284 285 286 287 288

  Scenario: Enterprise fork using regular HTTP
    Given the GitHub API server:
      """
      before {
        halt 400 unless request.env['HTTP_X_ORIGINAL_SCHEME'] == 'http'
289
        halt 400 unless request.env['HTTP_X_ORIGINAL_PORT'] == '80'
290 291
        halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token FITOKEN'
      }
292 293 294 295
      post('/api/v3/repos/evilchelu/dotfiles/forks', :host_name => 'git.my.org') {
        status 202
        json :name => 'dotfiles', :owner => { :login => 'mislav' }
      }
296 297 298 299 300 301
      """
    And the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git"
    And I am "mislav" on http://git.my.org with OAuth token "FITOKEN"
    And "git.my.org" is a whitelisted Enterprise host
    When I successfully run `hub fork`
    Then the url for "mislav" should be "git@git.my.org:mislav/dotfiles.git"
302 303 304 305 306 307 308 309 310 311 312 313 314 315

  Scenario: Fork a repo to a specific organization
    Given the GitHub API server:
      """
      get('/repos/acme/dotfiles') { 404 }
      post('/repos/evilchelu/dotfiles/forks') {
        assert :organization => "acme"
        status 202
        json :name => 'dotfiles', :owner => { :login => 'acme' }
      }
      """
    When I successfully run `hub fork --org=acme`
    Then the output should contain exactly "new remote: acme\n"
    Then the url for "acme" should be "git@github.com:acme/dotfiles.git"