Skip to content

Conversation

@begedin
Copy link
Contributor

@begedin begedin commented Oct 24, 2017

  • Adds GitHub request pagination
  • Adds repository issue syncing
  • Adds acceptance testing of the GitHub API

Closes #1109

@begedin
Copy link
Contributor Author

begedin commented Oct 24, 2017

Note that if we want to figure out the eagier approach, we could still do it in a semi-streamable fashion.

For example, we can get a stream of requests, then evaluate it using Stream.chunk_every

@joshsmith joshsmith force-pushed the github-pagination branch 4 times, most recently from a369701 to db55359 Compare October 28, 2017 01:34

Application.put_env(:code_corps, :github, old_mock)
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses the real API to test. I feel fairly confident that we should introduce some acceptance tests rather than letting our production server serve as that fallback. They should be kept to a bare minimum (like in this case testing a sync of a repository should only be done maybe when merging from staging to master).

I'm not comfortable right now, though, with the best way to do this with tags. Could use thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the perfect approach is, but we could make a command alias, for example mix test.acceptance, which basically calls mix test --include :acceptance

Then we setup mix test to auto-exclude tests with the tag :acceptance.

If we want to use the same test in acceptance and mock API mode, that's probably also doable, but we'll have to be creative. I'm not sure what the approach would be in that case.


{:ok, issues} = Repository.issues(github_repo)

assert Enum.count(issues) == 8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't actually use the with_real_api right now. It should.

is_after = current_time |> Timex.after?(previous_time)
is_equal = current_time |> Timex.equal?(previous_time)
after_or_equal = is_after || is_equal
case after_or_equal do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing is testing for this change yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with creating an issue and doing it separately.


def get_all(url, headers, options) do
HTTPoison.start
{:ok, response} = HTTPoison.get(url, headers, options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should likely be modified to call into a more central place so we can mock the %HTTPoison.Response{} (headers included). Otherwise it will be hard to test pagination.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we have an API.Gateway which simply has a request method that calls HTTPosion. Response parsing can be done in this module. We then mock the gateway in tests.

@joshsmith
Copy link
Contributor

Coverage of GitHub.API has gone down due to the defdelegate get_all

Copy link
Contributor Author

@begedin begedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some comments here, hope that helps.


def get_all(url, headers, options) do
HTTPoison.start
{:ok, response} = HTTPoison.get(url, headers, options)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we have an API.Gateway which simply has a request method that calls HTTPosion. Response parsing can be done in this module. We then mock the gateway in tests.

1 -> first_page
total ->
first_page ++ get_remaining_pages(total, url, headers, options) |> List.flatten
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With having a separate gateway, our marshall_response could then

  • check if the headers contains a "Links" key
  • if it does (and optionally, doable in a separate PR, if an option is set to get all), it calls this code which makes additional requests for further pages

This isn't absolutely needed in this PR, but could be an approach

is_after = current_time |> Timex.after?(previous_time)
is_equal = current_time |> Timex.equal?(previous_time)
after_or_equal = is_after || is_equal
case after_or_equal do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with creating an issue and doing it separately.


Application.put_env(:code_corps, :github, old_mock)
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the perfect approach is, but we could make a command alias, for example mix test.acceptance, which basically calls mix test --include :acceptance

Then we setup mix test to auto-exclude tests with the tag :acceptance.

If we want to use the same test in acceptance and mock API mode, that's probably also doable, but we'll have to be creative. I'm not sure what the approach would be in that case.

@joshsmith joshsmith merged commit d5b2b25 into develop Oct 28, 2017
@joshsmith joshsmith deleted the github-pagination branch October 28, 2017 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants