Skip to content

Commit 99a46f4

Browse files
committed
Add the /crate/foo/reverse_dependencies route.
This connects the web-app to the back-end API and allows it to display a list of all the reverse dependencies of a crate as a /reverse_dependencies subroute. This uses the same format as the /versions route.
1 parent da5bfeb commit 99a46f4

File tree

7 files changed

+74
-0
lines changed

7 files changed

+74
-0
lines changed

app/models/crate.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ export default DS.Model.extend({
2020
owners: DS.hasMany('users', {async: true}),
2121
version_downloads: DS.hasMany('version-download', {async: true}),
2222
keywords: DS.hasMany('keywords', {async: true}),
23+
reverse_dependencies: DS.hasMany('reverse-dependency', {async: true}),
2324
});

app/models/reverse-dependency.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Dependency from 'cargo/models/dependency';
2+
3+
export default Dependency;

app/router.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Router.map(function() {
1414
this.resource('crate', { path: '/crates/*crate_id' }, function() {
1515
this.route('download');
1616
this.route('versions');
17+
this.route('reverse_dependencies');
1718
});
1819
this.route('me', function() {
1920
this.route('crates');
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Ember from 'ember';
2+
import Crate from 'cargo/models/crate';
3+
4+
export default Ember.Route.extend({
5+
afterModel: function(data) {
6+
console.log("afterModel");
7+
if (data instanceof Crate) {
8+
return data.get('reverse_dependencies');
9+
} else {
10+
return data.crate.get('reverse_dependencies');
11+
}
12+
},
13+
14+
setupController: function(controller, data) {
15+
if (data instanceof Crate) {
16+
data = {crate: data, reverse_dependencies: null};
17+
}
18+
this._super(controller, data.crate);
19+
},
20+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<div class='all-versions-back'>
2+
{{#link-to 'crate' this}}&#11013; Back to Main Page{{/link-to}}
3+
</div>
4+
5+
<div class='info'>
6+
<span class='small'>
7+
All <span class='num'>{{ reverse_dependencies.length }}</span>
8+
reverse dependencies of <span class='num'>{{ name }}</span>
9+
</span>
10+
</div>
11+
12+
<div id='crate-all-reverse-dependencies' class='white-rows'>
13+
{{#each model.reverse_dependencies}}
14+
<div class='row'>
15+
<div>
16+
{{#link-to 'crate' crate_id}}{{crate_id}}{{/link-to}} requires {{req}}
17+
{{#link-to 'crate' this}}{{ num }}{{/link-to}}
18+
</div>
19+
{{#link-to 'crate' this class='arrow'}}
20+
<img src="/assets/right-arrow-all-versions.png"/>
21+
{{/link-to}}
22+
</div>
23+
{{/each}}
24+
</div>

src/krate.rs

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ pub struct CrateLinks {
6969
pub version_downloads: String,
7070
pub versions: Option<String>,
7171
pub owners: Option<String>,
72+
pub reverse_dependencies: String,
7273
}
7374

7475
impl Crate {
@@ -240,6 +241,7 @@ impl Crate {
240241
version_downloads: format!("/api/v1/crates/{}/downloads", name),
241242
versions: versions_link,
242243
owners: Some(format!("/api/v1/crates/{}/owners", name)),
244+
reverse_dependencies: format!("/api/v1/crates/{}/reverse_dependencies", name)
243245
},
244246
}
245247
}

src/tests/krate.rs

+23
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ struct CrateResponse { krate: EncodableCrate, versions: Vec<EncodableVersion> }
3232
#[deriving(Decodable)]
3333
struct Deps { dependencies: Vec<EncodableDependency> }
3434
#[deriving(Decodable)]
35+
struct RevDeps { reverse_dependencies: Vec<EncodableDependency> }
36+
#[deriving(Decodable)]
3537
struct Downloads { version_downloads: Vec<EncodableVersionDownload> }
3638

3739
#[test]
@@ -691,3 +693,24 @@ fn bad_keywords() {
691693
::json::<::Bad>(&mut response);
692694
}
693695
}
696+
697+
#[test]
698+
fn reverse_dependencies() {
699+
let (_b, _app, mut middle) = ::app();
700+
let user = ::user("foo");
701+
let c1 = ::krate("foo");
702+
let c2 = ::krate("bar");
703+
middle.add(::middleware::MockUser(user.clone()));
704+
middle.add(::middleware::MockDependency(c1.clone(), c2.clone()));
705+
let rel = format!("/api/v1/crates/{}/1.0.0/reverse_dependencies", c2.name);
706+
let mut req = MockRequest::new(conduit::Get, rel.as_slice());
707+
let mut response = ok_resp!(middle.call(&mut req));
708+
let deps = ::json::<RevDeps>(&mut response);
709+
assert_eq!(deps.reverse_dependencies[0].crate_id.as_slice(), &*c1.name);
710+
drop(req);
711+
712+
let rel = format!("/api/v1/crates/{}/1.0.2/reverse_dependencies", c1.name);
713+
let mut req = MockRequest::new(conduit::Get, rel.as_slice());
714+
let mut response = ok_resp!(middle.call(&mut req));
715+
::json::<::Bad>(&mut response);
716+
}

0 commit comments

Comments
 (0)