diff --git a/app/helpers/clean-repo-url.js b/app/helpers/clean-repo-url.js
new file mode 100644
index 00000000..bd6590ba
--- /dev/null
+++ b/app/helpers/clean-repo-url.js
@@ -0,0 +1,7 @@
+import { helper } from '@ember/component/helper';
+
+export function cleanRepoUrl([repoUrl]) {
+ return (repoUrl || '').replace(/\.git$/, '');
+}
+
+export default helper(cleanRepoUrl);
diff --git a/app/templates/components/addon-source-usages.hbs b/app/templates/components/addon-source-usages.hbs
index c5b59a2e..df3e06cb 100644
--- a/app/templates/components/addon-source-usages.hbs
+++ b/app/templates/components/addon-source-usages.hbs
@@ -7,7 +7,7 @@
{{#if usages}}
{{#each visibleUsages as |usage|}}
-
+
{{usage.filename}}:{{usage.line_number}}
{{#each usage.lines as |line|}}
diff --git a/tests/acceptance/code-search-test.js b/tests/acceptance/code-search-test.js
index edf6efec..a418537f 100644
--- a/tests/acceptance/code-search-test.js
+++ b/tests/acceptance/code-search-test.js
@@ -601,6 +601,49 @@ module('Acceptance | code search', function(hooks) {
assert.dom('.test-filtered-result-info').containsText('0 usages', 'filtered usage count is 0');
});
+ test('fixes links to code when repo URL ends with .git', async function(assert) {
+ let addon = server.create('addon', {
+ name: 'ember-try',
+ repositoryUrl: 'https://github.com/ember-cli/ember-try.git'
+ });
+
+ server.get('/search/addons', () => {
+ return {
+ results: [
+ {
+ addon: addon.id,
+ count: 1
+ }
+ ]
+ };
+ });
+
+ server.get('/search/source', () => {
+ return {
+ /* eslint-disable camelcase */
+ results: [
+ {
+ line_number: 52,
+ filename: 'app/services/fake-service.js',
+ lines: [
+ { text: 'if (addonData) {', number: 51 },
+ { text: 'addons.pushObject({ addon: addonData.addon });', number: 52 },
+ { text: '}', number: 53 }
+ ]
+ }
+ ]
+ /* eslint-disable camelcase */
+ };
+ });
+
+ await visit('/code-search');
+ await fillIn('#code-search-input', 'TestEm.afterTests');
+ await click('.test-submit-search');
+ await click('.test-usage-count');
+
+ assert.dom('.filename').hasAttribute('href', 'https://github.com/ember-cli/ember-try/tree/master/app/services/fake-service.js#L52');
+ });
+
function searchResults(addons) {
return addons.map((addon) => {
return {
diff --git a/tests/integration/helpers/clean-repo-url-test.js b/tests/integration/helpers/clean-repo-url-test.js
new file mode 100644
index 00000000..7c001b0c
--- /dev/null
+++ b/tests/integration/helpers/clean-repo-url-test.js
@@ -0,0 +1,34 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import hbs from 'htmlbars-inline-precompile';
+
+module('Integration | Helper | clean-repo-url', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it removes trailing .git from repo URLs', async function(assert) {
+ this.set('repoUrl', 'http://example.com/someone/something.git');
+
+ await render(hbs`{{clean-repo-url repoUrl}}`);
+
+ assert.equal(this.element.textContent.trim(), 'http://example.com/someone/something');
+ });
+
+ test('it does not remove non-trailing ".git"', async function(assert) {
+ let repoUrl = 'http://example.com/someone.git/something';
+ this.set('repoUrl', repoUrl);
+
+ await render(hbs`{{clean-repo-url repoUrl}}`);
+
+ assert.equal(this.element.textContent.trim(), repoUrl);
+ });
+
+ test('it does nothing to URLs that lack .git', async function(assert) {
+ let repoUrl = 'http://example.com/someone/something';
+ this.set('repoUrl', repoUrl);
+
+ await render(hbs`{{clean-repo-url repoUrl}}`);
+
+ assert.equal(this.element.textContent.trim(), repoUrl);
+ });
+});