-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added basic support for [hockeyapp] #2055
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for submitting this. All the major stuff is already looking good. I've left some comments to look at but most of them should be quite small points.
async handle({ apptoken, appid }) { | ||
const json = await this.fetch({ apptoken, appid }) | ||
|
||
if (json.app_versions === undefined || json.app_versions.length === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your schema says that the app_versions
key must be an array.
How does the situation where json.app_versions === undefined
occur?
Also, given there are some custom criteria here for the 'not found' response, can we have service tests covering these cases please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The undefined check is just a sanity check but as it will be checked by Joi anyways I will remove the undefined check and rely on that. Also adding the test case you mentioned.
version = latestVersionObject.version | ||
} | ||
|
||
return this.constructor.render({ version: version }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor style point: This could just be return this.constructor.render({ version })
static get examples() { | ||
return [ | ||
{ | ||
exampleUrl: 'hockeyapp/simple', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've set up a staging deploy for this at https://shields-staging-pr-2055.herokuapp.com/#/ and this example give me an invalid message: https://shields-staging-pr-2055.herokuapp.com/hockeyapp/v/hockeyapp/simple.svg Can you take a look. The example should return a valid response
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue here as with the test case that hits the live api - which account should I use for this example?
|
||
t.create('Invalid AppToken or AppId') | ||
.get('hockeyapp/v/1234/1234.json') | ||
.expectJSONTypes({ name: 'hockeyapp', value: 'invalid' }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're just comparing to an object literal, we use expectJSON()
in preference to expectJSONTypes()
- it gives us a more meaningful error message if it fails :)
t.create('Invalid AppToken or AppId') | ||
.get('hockeyapp/v/1234/1234.json') | ||
.expectJSONTypes({ name: 'hockeyapp', value: 'invalid' }) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have at least one valid case test in the suite which hits the live API and doesn't mock the response. I realise it is unusual practice for unit tests to depend on an external service ("don't test what you don't own") but we integrate with hundreds of services. If an upstream API changes or goes away, we need a test to start failing on the daily build otherwise we won't notice it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally understand that but we would have to rely on an app token that has to be obtained with a real account at https://hockeyapp.net - how do you handle this situation?
Thanks for having a look at those comments.
Any real app token would be fine (e.g: one of your own). Something that is stable is preferred :) an app you plan to delete in the near future would be an unhelpful choice. By the looks of it, you can generate an app token with read-only permissions. See: https://support.hockeyapp.net/kb/api/api-basics-and-authentication#authentication-api Just to understand better (I had not heard of this service until reviewing this PR so I don't know the in's and out's of it - you'll have to bring me up to speed), would be there be a negative consequence to a user of exposing a read-only app token? e.g: would that token allow someone to also access sensitive information about your account? If so, this would probably not be a suitable contribution for shields.io (although you might want to run it on a self-hosted instance). We shouldn't encourage our users to expose a token which allows access to protected info in their public readme. |
Thank you for getting back. As you have mentioned it all depends on the scope of the app token (e.g. just set it to the scope of a specific app and read only) which would make it perfectly sufficient to expose the token publicly. At least as far as I can tell by the docs. I'm looking into the options of how to make the example endpoint stable and will update the PR accordingly. |
OK, thanks. Given it is important for users to use the correct token scope here, lets make this a little bit more clear. I'd suggest 2 things:
e.g: {
exampleUrl: '78e9ae0287ca4a07b2cbbb1338e1c71b/7e53b1f0ebe171be1b9004ff04a2f663',
urlPattern: ':read-only-token/:appid',
staticExample: this.render({ version: '1.0.0' }),
documentation: "bla bla some extra info here"
} |
@@ -25,7 +25,7 @@ t.create('Android App') | |||
], | |||
}) | |||
) | |||
.expectJSONTypes({ name: 'hockeyapp', value: isVPlusDottedVersionAtLeastOne }) | |||
.expectJSON({ name: 'hockeyapp', value: isVPlusDottedVersionAtLeastOne }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify my previous comment:
We use .expectJSON()
when comparing to an object literal e.g: .expectJSON({ name: 'hockeyapp', value: 'invalid' })
but .expectJSONTypes()
is necessary when we're validating against an expression, so these ones still need to be .expectJSONTypes()
. You'll probably find these are failing.
Sorry this is a bit fiddly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for clarifying. Will fix this.
I'm a bit confused about those tests failing, because the requests work on my local machine after trying them manually. I see them failing when I run them locally, too. |
Aah. The reason the service test fail is because when you create the test object with I'm aware this is currently not well documented. As you've probably noticed, we're currently transitioning from one architecture to another. I finished updating the tutorial earlier this week. I'm planning to work on updating the service test docs next week. Latest changes are looking good. If you can get those tests passing and add the additional case which hits a live endpoint without mocking, this should be good to go 👍 . |
@TobiasRoeddiger - are you interested in finishing this? I think there is probably only the minor fix to get the service tests passing in order to get this merged. |
Yes I am! Sorry but had some really important things to do and this just slipped out of scope. |
@TobiasRoeddiger Would be great to get this merged! Would you be up for wrapping this up? |
Would anyone else like to take a few moments to wrap this up? |
I'm really sorry.
|
Installing imagemagick should fix that. If it doesn’t you could also safely ignore or those few tests, or |
return 'version' | ||
} | ||
|
||
static get url() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this signature should now be static get route()
Given that you're only modifying service code here, you may want to just run a |
async handle({ apitoken, appid }) { | ||
const json = await this.fetch({ apitoken, appid }) | ||
|
||
if (json.app_versions.length === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could move this check to the schema instead:
app_versions: Joi.array()
.items(
Joi.Object({ ... })
)
.min(1),
...
static get url() { | ||
return { | ||
base: 'hockeyapp/v', | ||
format: '(.+)/(.+)', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can switch this to use pattern now: remove the format
and capture
keys and replace them with:
pattern: ':apioken+/:appid+'
that's assuming those two params both need the full (.+)
capture group
Hey @TobiasRoeddiger would you have a moment to address these comments? It would be great to get this shipped! 🚀 |
Feel free to reopen this when you have time! And, same goes for anyone else who would like to pick this up. You can grab the commits from this branch, merge in latest master, address the comments, and open a new PR. |
Hello. I added basic support for a badge for Hockeyapp deployments for iOS and Android. Thank you for the awesome project!