-
Notifications
You must be signed in to change notification settings - Fork 683
Add a link to browse crate source on docs.rs #12550
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import { expect, test } from '@/e2e/helper'; | ||
| import { http, HttpResponse } from 'msw'; | ||
|
|
||
| test.describe('Route | crate.version | source link', { tag: '@routes' }, () => { | ||
| test('show docs.rs source link even if non-docs.rs documentation link is specified', async ({ page, msw }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo', documentation: 'https://foo.io/docs' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source/'); | ||
|
Check failure on line 10 in e2e/routes/crate/version/source-link.spec.ts
|
||
| }); | ||
|
|
||
| test('show no source link if there are no related docs.rs builds', async ({ | ||
| page, | ||
| msw, | ||
| }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('not found', { status: 404 }); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.getByRole('link', { name: 'crates.io', exact: true })).toHaveCount(1); | ||
|
|
||
| await expect(page.locator('[data-test-source-link] a')).toHaveCount(0); | ||
| }); | ||
|
|
||
| test('show source link if `documentation` is unspecified and there are related docs.rs builds', async ({ | ||
| page, | ||
| msw, | ||
| }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let response = HttpResponse.json({ | ||
| doc_status: true, | ||
| version: '1.0.0', | ||
| }); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source/'); | ||
| }); | ||
|
|
||
| test('show no source link if `documentation` points to docs.rs and there are no related docs.rs builds', async ({ | ||
| page, | ||
| msw, | ||
| }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('not found', { status: 404 }); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveCount(0); | ||
| }); | ||
|
|
||
| test('show source link if `documentation` points to docs.rs and there are related docs.rs builds', async ({ | ||
| page, | ||
| msw, | ||
| }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let response = HttpResponse.json({ | ||
| doc_status: true, | ||
| version: '1.0.0', | ||
| }); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source'); | ||
|
Check failure on line 74 in e2e/routes/crate/version/source-link.spec.ts
|
||
| }); | ||
|
|
||
| test('ajax errors are ignored, but show no source link', async ({ page, msw }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await msw.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('error', { status: 500 }); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveCount(0); | ||
| }); | ||
|
|
||
| test('empty docs.rs responses are ignored, still show source link', async ({ page, msw }) => { | ||
| let crate = await msw.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await msw.db.version.create({ crate, num: '0.6.2' }); | ||
|
|
||
| let response = HttpResponse.json({}); | ||
| msw.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await page.goto('/crates/foo'); | ||
| await expect(page.locator('[data-test-source-link] a')).toHaveAttribute('href', 'https://docs.rs/crate/foo/0.6.2/source/'); | ||
|
Check failure on line 96 in e2e/routes/crate/version/source-link.spec.ts
|
||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| import { visit } from '@ember/test-helpers'; | ||
| import { module, test } from 'qunit'; | ||
|
|
||
| import { http, HttpResponse } from 'msw'; | ||
|
|
||
| import { setupApplicationTest } from 'crates-io/tests/helpers'; | ||
|
|
||
| module('Route | crate.version | source link', function (hooks) { | ||
| setupApplicationTest(hooks); | ||
|
|
||
| test('shows docs.rs source link even if non-docs.rs documentation link is specified', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo', documentation: 'https://foo.io/docs' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').hasAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source/'); | ||
| }); | ||
|
|
||
| test('show no source link if there are no related docs.rs builds', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('not found', { status: 404 }); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').doesNotExist(); | ||
| }); | ||
|
|
||
| test('show source link if `documentation` is unspecified and there are related docs.rs builds', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let response = HttpResponse.json({ doc_status: true, version: '1.0.0' }); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').hasAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source/'); | ||
| }); | ||
|
|
||
| test('show no source link if `documentation` points to docs.rs and there are no related docs.rs builds', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('not found', { status: 404 }); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').doesNotExist(); | ||
| }); | ||
|
|
||
| test('show source link if `documentation` points to docs.rs and there are related docs.rs builds', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let response = HttpResponse.json({ doc_status: true, version: '1.0.0' }); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').hasAttribute('href', 'https://docs.rs/crate/foo/1.0.0/source/'); | ||
| }); | ||
|
|
||
| test('ajax errors are ignored, but show no source link', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await this.db.version.create({ crate, num: '1.0.0' }); | ||
|
|
||
| let error = HttpResponse.text('error', { status: 500 }); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => error)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').doesNotExist(); | ||
| }); | ||
|
|
||
| test('empty docs.rs responses are ignored, still show source link', async function (assert) { | ||
| let crate = await this.db.crate.create({ name: 'foo', documentation: 'https://docs.rs/foo/0.6.2' }); | ||
| await this.db.version.create({ crate, num: '0.6.2' }); | ||
|
|
||
| let response = HttpResponse.json({}); | ||
| this.worker.use(http.get('https://docs.rs/crate/:crate/:version/status.json', () => response)); | ||
|
|
||
| await visit('/crates/foo'); | ||
| assert.dom('[data-test-source-link] a').hasAttribute('href', 'https://docs.rs/crate/foo/0.6.2/source/'); | ||
| }); | ||
| }); |
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 we can show the link more often.
from what I see,
hasDocsRsLinkis based on our status-json result (doc_statusin there).But we also have & host the source when:
The only edge cases here would be when the build is queued, or we didn't get the update from the registry yet.
I think you're good in just checking if you have a result from our status endpoint, no matter what you see in
doc_statusThere 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.
there is also rust-lang/docs.rs#2762 where we would try to serve a nice page even for just queued releases