Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
Choose a Base Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
Choose a Head Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
Commits on Jun 02, 2015
Let users change their email addresses
Fixes #174.

account.html:

- Add a new "Change Your Email Address" form

accounts/views.py:

- Add email to the user dict returned at /app?__formid__=profile (or
  session.profile() in Angular)

- When resetting the form after a successful submission, put the new (or
  unchanged) email address into the user dict returned in the response.
  AccountController needs this (see below).

account-controller.coffee:

- Add $scope.email (the user's current email address), to use for placeholder
  text in the email form field.

- After a successful form submission set $scope.email to the one from the
  response. This sets the placeholder text in the email field to the new value,
  instead of continuing to show the old email address as placeholder.

- Add changeEmail() method to receive email form submissions.
Begin adding frontend tests for changing email
Begin adding frontend tests for the new AccountController code that
deals with the new form for changing the logged-in user's email address.

I've done this as a new top-level describe() with a new way of writing
Angular controller tests, rather than adding to the stuff already in
account-controller-test.coffee.

The aims of this way of writing tests is to make the tests easier to understand
and modify (either to fix a broken test or to add new ones) by:

- Reducing special Angular knowledge needed to understand the tests

- Reducing globals (both global variables and beforeEach() functions) used in
  tests.

  These increase the "travel" needed to understand a given test method because
  you have to read the whole test module to understand everything that happens
  before the test runs and what all the global variables the test uses are.

  The aim is that reading only the test function (and not the rest of the code
  in the file) should be enough to understand the test.

  Similarly I shouldn't have to read and understand the whole test file to add
  a new test.

  Globals and beforeEach()'s also tie the tests together. For example if a
  bunch of stub services and a controller are created in beforeEach() functions
  then any new tests added to the file inherit this stubbing behaviour even
  though they may not want it or may need something else. This again makes
  changing or adding just one test harder - need to understand the whole file,
  changes made for one test may break other tests.

Implementation notes:

- Used a new top-level describe(), didn't want to inherit all the globals,
  beforeEach()'s and stubbing of the existing one.

- Because we now have two top-level describe()s had to use a try ... catch in
  the second one to avoid creating the "h" Angular module twice.

- Tried to decouple the tests from Angular as much as possible, reduce the
  amount of Angular knowledge (especially about providing and injecting
  dependencies) needed to understand the tests.

  Angular's $provide isn't used at all, and inject() (which I don't think can
  be removed completely) is contained in two helper functions.

- Rather than a beforeEach() and global variables we use a controller()
  function that creates the AccountController and stubs for the services it
  depends on and returns an object of all of them.

  Tests can then call controller() and use destructuring assignment to get only
  the bits they need.

  Every variable used in a test method is defined in the test method
  (sometimes by calling a helper function and getting a return value).

- controller() by default uses minimal stubbing, but the caller can optionally
  pass in their own object for each of the stubbed dependencies.
Add frontend tests for change email form
Quite a lot of repetition in these tests, some shared helper functions needed.
Move current email address out of <input> fields
Move the user's current email address out of the placeholder attribute
of the new email address <input> field. Just put it in a <p> instead.
This is much better for usability.
Fix email address display bug
1. Go to the Change Your Email Address form
2. Type in a new email address (twice) and your password
3. Select part of the text showing your current email address with the
   cursor
4. Click Update

=> The display of your current email address is updated to a nonsense
value.

This commit fixes the issue, your email address will be displayed
correctly.
Add server-side validation when changing email
This prevents users from changing their emails to invalid values that
still pass Angular's frontend validation, such as "foo@bar", or to an
email address already used by another account.
Factor horus out of edit_profile()
Move horus mess into a helper function. This should make edit_profile()
more testable.
Refactor edit_profile() tests
Make the tests fewer and a lot simpler and with less mocking.

Also refactor edit_profile() a little more to improve testability even
more.
Put paths to asset build tools back in conf/production.ini
We shouldn't have to alter $PATH just to build the production
extensions.
Remove unneccesary call
The hub init process has nothing to do with this variable.
Commits on Jun 03, 2015
Don't explode on empty bodies in AsyncFormViewMapper
This is a quick fix for an error currently in staging which prevents
logout from working.
Set a server-side default for the NIPSA column
This should really be done for all migrations that involve adding a
non-nullable column. This makes it possible to run the migration in
staging without breaking production.

You will need to throw away your development database (or do something
fiddly like downgrade to 4a97f680ecca first and then upgrade to
29d0200ba8a9).
View
@@ -14,6 +14,7 @@
- Added support for URL parameters to the Atom feed at ``/stream.atom``.
For example: ``/stream.atom?user=seanh`` or
``/stream.atom?user=seanh&tags=foo,bar``.
- Users can now change their email addresses using the Account form (#2131)
0.4.0 (2015-05-05)
==================
View
@@ -29,6 +29,7 @@ clean:
rm -f h/static/scripts/config.*js
rm -f h/static/scripts/hypothesis.*js
rm -f h/static/styles/*.css
rm .coverage
dev: deps
@gunicorn --reload --paste conf/development.ini
View
@@ -69,7 +69,10 @@ webassets.cache: False
webassets.cache_max_age: 31536000
webassets.manifest: False
webassets.static_view: True
webassets.browserify_bin: ./node_modules/.bin/browserify
webassets.browserify_extra_args: --extension=.coffee
webassets.cleancss_bin: ./node_modules/.bin/cleancss
webassets.uglifyjs_bin: ./node_modules/.bin/uglifyjs
[filter:proxy-prefix]
@@ -0,0 +1,179 @@
=============================
Building the Chrome extension
=============================
This document describes how to build an instance of the
`Hypothesis Chrome extension`_ based on the current contents of your working
tree and install it in Chrome.
.. _Hypothesis Chrome extension: https://chrome.google.com/webstore/detail/hypothesis-web-pdf-annota/bjfhmglciegochdpefhhlphglcehbmek
---------------------------------------------
Building the Chrome extension for development
---------------------------------------------
To build and install a local development instance of the Chrome extension:
1. Do an :doc:`h development install </hacking/install>`.
2. Run this command to build the Chrome extension:
.. code-block:: bash
hypothesis-buildext conf/development.ini chrome --base 'http://127.0.0.1:5000'
.. note::
When you run the ``hypothesis-buildext`` command without a ``--assets``
argument (as in the command above) it builds a Chrome extension
configured to load its assets (JavaScript, CSS, ...) from the ``--base``
URL (in the command above: your local development instance of the
Hypothesis web app running at http://127.0.0.1:5000). That is: the web
app serves these JavaScript, CSS and other files and the Chrome extension
is configured to request them from the web app.
This is the most convenient way to build the extension for development
because you can make changes to these source files and have your changes
take effect without having to re-run the ``hypothesis-buildext`` command.
But there are some issues with building the extension this way that you
should be aware of:
1. The extension will fail to load on ``https://`` pages and you'll see a
*mixed content* warning in the console. To test the extension on
``https`` sites see
`Building an https version of the Chrome extension`_.
2. The extension will fail to load on some sites that use
`Content Security Policy`_. To test the extension on these sites see
`Building the Chrome extension for production`_.
3. Go to ``chrome://extensions/`` in Chrome.
4. Tick **Developer mode**.
5. Click **Load unpacked extension**.
6. Browse to the ``h/build/chrome/`` directory where the extension was built
and select it.
Your extension should be working now! Remember that it communicates with your
local h instance, so you need to have h running to use the extension.
.. _Content Security Policy: http://en.wikipedia.org/wiki/Content_Security_Policy
-------------------------------------------------
Building an https version of the Chrome extension
-------------------------------------------------
To use the Chrome extension on ``https`` sites you need to serve the
extension's assets over ``https``:
1. :doc:`Run your local h instance using https </hacking/ssl>`.
2. Build the extension with an ``https`` base URL:
.. code-block:: bash
hypothesis-buildext conf/development.ini chrome --base 'https://127.0.0.1:5000'
3. Follow steps 3-6 from `Building the Chrome extension for development`_
above to install the extension in Chrome. (If you've already installed the
extension and you just rebuilt it for ``https`` then you don't need to do
anything.)
Your extension should now work on ``https`` sites.
--------------------------------------------
Building the Chrome extension for production
--------------------------------------------
The production Chrome extension doesn't load its assets from a website. Instead
we pack the asset files into the extension itself and it loads them from
``chrome-extension://`` URLs. This makes the extension faster and means that it
works on sites whose `Content Security Policy`_ would prevent assets from being
loaded from another site.
This method usually isn't convenient for development because you have to re-run
the ``hypothesis-buildext`` command after changing the source files for any of
the assets, but if you want to test the extension on a site that uses Content
Security Policy you should follow these steps:
1. Install some additional dependencies needed to build a production extension:
.. code-block:: bash
pip install -r requirements.txt
2. Follow `Building an https version of the Chrome extension`_ above to build
and install an ``https`` development extension.
3. Copy your extension's ID from the ``chrome://extensions`` page.
Chrome generates this ID the first time you install the extension will reuse
it each time your rebuild or reinstall the extension.
4. Rebuild the Chrome extension with packed assets and using ``production.ini``
instead of ``development.ini``:
.. code-block:: bash
hypothesis-buildext conf/production.ini chrome
--base 'https://127.0.0.1:5000'
--assets 'chrome-extension://<id>/public'
Replace ``<id>`` with the ID of your extension from the
``chrome://extensions`` page.
Your extension should now work on sites with ``https`` and Content Security
Policy.
---------------
Troubleshooting
---------------
Mixed Content errors in the console
===================================
The extension fails to load and you see *Mixed Content* errors in the console.
See `Building an https version of the Chrome extension`_.
Insecure Response errors in the console
=======================================
You've built the extension with an ``https`` base URL, the extension fails to
load and you see ``net::ERR_INSECURE_RESPONSE`` errors in the console.
You need to open https://127.0.0.1:5000 (or whatever ``--base`` you gave)
and tell Chrome to allow access to the site even though the certificate isn't
known.
Content Security Policy errors in the console
=============================================
The extension fails to load and you see
*Refused to load the ... because it violates the following Content Security Policy directive: ...*
errors in the console.
See `Building the Chrome extension for production`_.
Empty Response errors in the console
====================================
The extension fails to load and you see
``GET http://127.0.0.:5000/... net::ERR_EMPTY_RESPONSE`` errors in the console.
This happens if you're running h on ``https`` but you've built the Chrome
extension with an ``http`` base URL. Either run h on ``http`` or rebuild the
extension with ``--base https://...``.
File Not Found errors in the console
====================================
The extension fails to load and you see ``net::ERR_FILE_NOT_FOUND`` errors in
the console. This can happen if you build the extension with
``conf/development.ini`` and ``--assets 'chrome-extension://<id>/public'``.
Packing assets is not supported with ``development.ini``, use
``conf/production.ini`` instead.
@@ -1,7 +1,8 @@
Building the browser extensions
###############################
==============================
Building the Firefox extension
==============================
To build the browser extensions, use the ``hypothesis-buildext`` tool::
To build the Firefox extension, use the ``hypothesis-buildext`` tool::
usage: hypothesis-buildext [-h] config_uri {chrome,firefox} ...
@@ -16,11 +17,10 @@ To build the browser extensions, use the ``hypothesis-buildext`` tool::
chrome build the Google Chrome extension
firefox build the Mozilla Firefox extension
At this point, a working extension should exist in either ``./build/chrome``
or ``./build/firefox``. If the development configuration was used, static
assets are loaded from the server. Start the application and ensure that the
assets are built by visiting the start page or by running the ``assets``
command::
At this point, a working extension should exist in ``./build/firefox``.
If the development configuration was used, static assets are loaded from the
server. Start the application and ensure that the assets are built by visiting
the start page or by running the ``assets`` command::
usage: hypothesis assets [-h] config_uri
@@ -29,4 +29,3 @@ command::
optional arguments:
-h, --help show this help message and exit
View
@@ -10,7 +10,8 @@ and how to contribute code or documentation to the project.
communications
cla
install
browser-extensions
chrome-extension
firefox-extension
submitting-a-pr
code-style
documentation
View
@@ -12,6 +12,12 @@
def post_fork(_server, _worker):
# Support back-ported SSL changes on Debian / Ubuntu
import _ssl
import gevent.hub
if not hasattr(_ssl, '_sslwrap'):
gevent.hub.PYGTE279 = True
try:
import psycogreen.gevent
psycogreen.gevent.patch_psycopg()
View
@@ -65,8 +65,12 @@ class User(UserMixin, Base):
sa.Unicode(30),
nullable=False,
unique=True)
# Not In Public Site Areas flag
nipsa = sa.Column(sa.BOOLEAN, default=False, nullable=False)
nipsa = sa.Column(sa.BOOLEAN,
default=False,
server_default=sa.sql.expression.false(),
nullable=False)
def _get_username(self):
return self._username
View
@@ -186,9 +186,15 @@ class EditProfileSchema(CSRFSchema):
)
email = colander.SchemaNode(
colander.String(),
validator=colander.All(colander.Email(), unique_email),
default='',
missing=colander.null
)
emailAgain = colander.SchemaNode(
colander.String(),
default='',
missing=colander.null,
)
password = colander.SchemaNode(
colander.String(),
title=_('Password'),
Oops, something went wrong.

Showing you all comments on commits in this comparison.

@tilgovi

This comment has been minimized.

Show comment
Hide comment
@tilgovi

tilgovi Jun 3, 2015

Contributor

🍕

Contributor

tilgovi commented on 06278fb Jun 3, 2015

🍕