Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Provide discovery via package.json #4507

Merged
merged 1 commit into from
Jun 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions gratipay/utils/ghost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

PACKAGE_JSON = '''\
{
"name": "ghost",
"version": "1.0.0-alpha.21",
"description": "Just a blogging platform.",
"author": "Ghost Foundation",
"homepage": "http://ghost.org",
"keywords": [
"ghost",
"blog",
"cms"
],
"repository": {
"type": "git",
"url": "git://github.com/TryGhost/Ghost.git"
},
"bugs": "https://github.com/TryGhost/Ghost/issues",
"contributors": "https://github.com/TryGhost/Ghost/graphs/contributors",
"license": "MIT",
"main": "./core/index",
"scripts": {
"start": "node index",
"test": "grunt validate --verbose",
"init": "yarn global add knex-migrator ember-cli grunt-cli && yarn install && grunt symlink && grunt init || true"
},
"engines": {
"node": "^4.5.0 || ^6.9.0"
},
"dependencies": {
"amperize": "0.3.4",
"archiver": "1.3.0",
"bcryptjs": "2.4.3",
"bluebird": "3.5.0",
"body-parser": "1.17.1",
"bookshelf": "0.10.3",
"brute-knex": "https://github.com/cobbspur/brute-knex/tarball/37439f56965b17d29bb4ff9b3f3222b2f4bd6ce3",
"bson-objectid": "1.1.5",
"chalk": "1.1.3",
"cheerio": "0.22.0",
"compression": "1.6.2",
"connect-slashes": "1.3.1",
"cookie-session": "1.2.0",
"cors": "2.8.3",
"csv-parser": "1.11.0",
"debug": "2.6.6",
"downsize": "0.0.8",
"express": "4.15.2",
"express-brute": "1.0.1",
"express-hbs": "1.0.4",
"extract-zip-fork": "1.5.1",
"fs-extra": "3.0.1",
"ghost-gql": "0.0.6",
"ghost-ignition": "2.8.11",
"ghost-storage-base": "0.0.1",
"glob": "5.0.15",
"gscan": "1.1.0",
"html-to-text": "3.2.0",
"icojs": "0.7.2",
"image-size": "0.5.2",
"intl": "1.2.5",
"intl-messageformat": "1.3.0",
"jsdom": "9.12.0",
"jsonpath": "0.2.11",
"knex": "0.12.9",
"knex-migrator": "2.0.16",
"lodash": "4.17.4",
"markdown-it": "8.3.1",
"markdown-it-footnote": "3.0.1",
"markdown-it-lazy-headers": "0.1.3",
"markdown-it-mark": "2.0.0",
"markdown-it-named-headers": "0.0.4",
"mobiledoc-dom-renderer": "0.6.5",
"moment": "2.18.1",
"moment-timezone": "0.5.13",
"multer": "1.3.0",
"mysql": "2.13.0",
"nconf": "0.8.4",
"netjet": "1.1.3",
"nodemailer": "0.7.1",
"oauth2orize": "1.8.0",
"passport": "0.3.2",
"passport-ghost": "2.3.1",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"path-match": "1.2.4",
"rss": "1.2.2",
"sanitize-html": "1.14.1",
"semver": "5.3.0",
"simple-dom": "0.3.2",
"simple-html-tokenizer": "0.4.1",
"superagent": "3.5.2",
"unidecode": "0.1.8",
"uuid": "3.0.1",
"validator": "6.3.0",
"xml": "1.0.1"
},
"optionalDependencies": {
"sqlite3": "3.1.8"
},
"devDependencies": {
"grunt": "1.0.1",
"grunt-bg-shell": "2.3.3",
"grunt-cli": "1.2.0",
"grunt-contrib-clean": "1.0.0",
"grunt-contrib-compress": "1.3.0",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-symlink": "^1.0.0",
"grunt-contrib-uglify": "2.0.0",
"grunt-contrib-watch": "1.0.0",
"grunt-cssnano": "2.1.0",
"grunt-docker": "0.0.11",
"grunt-express-server": "0.5.3",
"grunt-jscs": "3.0.1",
"grunt-mocha-cli": "2.1.0",
"grunt-mocha-istanbul": "5.0.2",
"grunt-shell": "1.3.1",
"grunt-subgrunt": "1.2.0",
"grunt-update-submodules": "0.4.1",
"istanbul": "0.4.5",
"jshint": "2.9.4",
"jshint-stylish": "2.2.1",
"matchdep": "1.0.1",
"minimist": "1.2.0",
"mocha": "3.3.0",
"nock": "9.0.13",
"rewire": "2.5.2",
"run-sequence": "1.2.2",
"should": "11.2.1",
"should-http": "0.1.1",
"sinon": "1.17.7",
"supertest": "3.0.0",
"tmp": "0.0.31"
},
"greenkeeper": {
"ignore": [
"glob",
"nodemailer",
"grunt",
"grunt-bg-shell",
"grunt-cli",
"grunt-contrib-clean",
"grunt-contrib-compress",
"grunt-contrib-copy",
"grunt-contrib-jshint",
"grunt-contrib-uglify",
"grunt-contrib-watch",
"grunt-docker",
"grunt-express-server",
"grunt-jscs",
"grunt-mocha-cli",
"grunt-mocha-istanbul",
"grunt-shell",
"grunt-subgrunt",
"grunt-update-submodules",
"sinon"
]
}
}'''
66 changes: 66 additions & 0 deletions scss/pages/npm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#npm {

#content {
.important-thing-at-the-top {
margin-bottom: 40px;
}
.nav {
margin: 0 20% 60px;

li {
width: 50%;
text-align: center;
display: block;
float: left;
margin: 0;
padding: 0;
a {
font: normal 24px/28px $Ideal;
display: block;
height: 64px;
padding: 18px 0 0;
margin: 0;
border-bottom: 0;

.textwrap {
color: $black;
display: inline-block;
border-bottom: 4px solid transparent;
}

&:hover {
background: none;
}

&.selected {
.textwrap {
border-bottom-color: $green;
font-weight: bold;
}
}
}
&:nth-child(1) a {
padding-left: 33%;
text-align: left;
}
&:nth-child(2) a {
padding-right: 33%;
text-align: right;
}
}
}
.discovery .sorry {
margin: 40px 0;
}

form.package-json {
margin-top: 30px;
}

textarea {
height: 192px;
width: 100%;
font: 10px/12px $Mono;
}
}
}
4 changes: 3 additions & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,20 @@ <h1><a href="/"><img src="{{ website.asset('gratipay.svg') }}"
{% block banner %}{% if banner %}<h1>{{ banner }}</h1>{% endif %}{% endblock %}
</div>

{% if page_id != 'npm' %}
<table id="notice">
<tr>
<td>&#x2605;</td>
<td>{{ _( "{nowrap}We have {a}integrated npm{_a} into Gratipay.{_nowrap}{_nowrap}"
, nowrap='<span class="nowrap">'|safe
, _nowrap='</span>'|safe
, a='<a href="https://gratipay.news/integrating-npm-39333109419d">'|safe
, a='<a href="/on/npm/">'|safe
, _a='</a>'|safe
) }}</td>
<td>&#x2605;</td>
</tr>
</table>
{% endif %}

<div id="main">
{% block main %}
Expand Down
4 changes: 2 additions & 2 deletions tests/py/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ def test_remove_notification(self):
alice.remove_notification('1234')
assert alice.notifications == ["abcd", "bcde"]

def test_blog_announcement(self):
assert 'integrating-npm-39333109419d">integrated' in self.client.GET('/').body
def test_star_announcement(self):
assert '/on/npm/">integrate' in self.client.GET('/').body
5 changes: 3 additions & 2 deletions tests/py/test_www_npm_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def setUp(self):

def test_anon_gets_signin_page_from_unclaimed(self):
body = self.client.GET('/on/npm/foo/').body
assert 'foo</a> npm package:' in body
assert 'foo</a> npm package on Gratipay:' in body

def test_auth_gets_send_confirmation_page_from_unclaimed(self):
self.make_participant('bob', claimed_time='now')
Expand Down Expand Up @@ -60,6 +60,7 @@ class Bulk(Harness):
def setUp(self):
self.make_package()

def test_anon_gets_signin_page(self):
def test_anon_gets_payment_flow(self):
body = self.client.GET('/on/npm/').body
assert 'Paste a package.json' in body
assert '0 out of all 1 npm package' in body
4 changes: 2 additions & 2 deletions tests/ttw/test_package_claiming.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ def setUp(self):
def visit_as(self, username):
self.visit('/')
self.sign_in(username)
self.visit('/on/npm/')
self.visit('/on/npm/?flow=receive')

def test_anon_gets_sign_in_prompt(self):
self.visit('/on/npm/')
self.visit('/on/npm/?flow=receive')
assert self.css('.important-button button').text == 'Sign in / Sign up'

def test_auth_without_email_gets_highlighted_link_to_email(self):
Expand Down
54 changes: 54 additions & 0 deletions tests/ttw/test_package_discovery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

from gratipay.testing import BrowserHarness


class Tests(BrowserHarness):

def assertDiscovery(self):
instructions = self.css('.instructions').text
assert instructions == 'Paste a package.json to find packages to pay for:'

def test_anon_gets_discovery_page_by_default(self):
self.visit('/on/npm/')
self.assertDiscovery()

def test_auth_also_gets_discovery_page_by_default(self):
self.make_participant('alice')
self.sign_in('alice')
self.visit('/on/npm/')
self.assertDiscovery()

def test_pasting_a_package_json_works(self):
self.make_package(name='amperize', description='Amperize!')
mysql = self.make_package(name='mysql', description='MySQL!', emails=['[email protected]'])
self.make_package(name='netjet', description='Netjet!', emails=['[email protected]'])
scape = self.make_package(name='scape', description='Reject!', emails=['[email protected]'])
self.claim_package(self.make_participant('alice'), 'amperize')
self.claim_package(self.make_participant('bob'), 'mysql')
self.claim_package(self.make_participant('goat'), 'scape')

admin = self.make_admin()
mysql.team.update(name='MySQL')
mysql.team.update_review_status('approved', admin)
scape.team.update_review_status('rejected', admin)

self.visit('/on/npm/')
self.css('textarea').fill('''\

{ "dependencies": {"scape": "...", "mysql": "...", "amperize": "..."}
, "optionalDependencies": {"netjet": "...", "falafel": "..."}
}

''')
self.css('form.package-json button').click()

names = [x.text for x in self.css('.listing-name')]
assert names == ['MySQL (mysql on npm)', 'scape', 'amperize', 'netjet', 'falafel']

statuses = [x.text[3:] for x in self.css('.listing-details .status')]
assert statuses == ['Approved', 'Rejected', 'Unreviewed', 'Unclaimed']

enabled = [not x.has_class('disabled') for x in self.css('td.item')]
assert enabled == [True, True, True, True, False]
1 change: 1 addition & 0 deletions www/assets/gratipay.css.spt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
@import "scss/pages/history";
@import "scss/pages/identities";
@import "scss/pages/team";
@import "scss/pages/npm";
@import "scss/pages/package";
@import "scss/pages/profile-edit";
@import "scss/pages/giving";
Expand Down
17 changes: 11 additions & 6 deletions www/on/npm/%package/index.html.spt
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,22 @@ if user.participant:
<p class="sorry important-thing-at-the-top">{{ _("No description available.") }}</p>
{% endif %}

<p class="instructions">
{{ _( 'Apply to accept payments for the {package_link} npm package:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>

{% if user.ANON %}
<p class="instructions">
{{ _( 'Claim the {package_link} npm package on Gratipay:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>
<div class="important-button">
{{ sign_in_using(button_class='large') }}
</div>
{% else %}
<p class="instructions">
{{ _( 'Apply to accept payments for the {package_link} npm package:'
, package_link=('<a href="' + package.remote_human_url + '">' + package_name + '</a>')|safe
) }}
</p>

{% if len(emails) == 0 %}
<p class="sorry">{{ _("No email addresses on file.") }}</p>
{% else %}
Expand Down
Loading