def setUp(self): # FIXME: Remove once everything else is TestCase-ified. db.delete(db.Query(keys_only=True)) memcache.flush_all() # Configure a basic HTTP client. self.http_client = app.test_client() # Capture outgoing email messages. self.emails = [] sendgrid = config.send_grid_client self._send, sendgrid.send = sendgrid.send, self.emails.append # Capture outgoing Slack messages. self.chats = [] self._send_chat = slack.send_chat slack.send_chat = lambda **kw: self.chats.append(kw) # Ensure that UUIDs are deterministic. self._uuid4 = uuid.uuid4 uuid.uuid4 = lambda: "ZZ-ZZ-ZZ" # Create simple entities to play with. self.listing_a = entities.Listing( title=u"Listing \u2606A", body=u"Body of \u2606A", posting_time=time.time() - 4 * 3600, seller="*****@*****.**", price=310, categories=["category:cars"], photos=["listing-a", "listing-a2"], admin_key="a_key", key_name="listing_a") self.listing_a.put() self.listing_b = entities.Listing( title=u"Listing \u2606B", body=u"Body of \u2606B", posting_time=time.time() - 24 * 3600, seller="*****@*****.**", price=7110, categories=["category:apartments"], photos=["listing-b", "listing-b2"], key_name="listing_b") self.listing_b.put() self.listing_c = entities.Listing( title=u"Listing \u2606C", body=u"Body of \u2606C", posting_time=0., seller="*****@*****.**", price=9105, categories=["category:appliances"], photos=[], admin_key="adminkey", key_name="listing_c") self.listing_c.put() # Allow very large diffs. self.maxDiff = None
def test_search(): entities.Listing(title="title for test", posting_time=1.0e5, key_name="search_test").put() assert tuple(helpers.fetch_shard("title")) == ("search_test", ) assert (tuple( x.permalink for x in helpers.run_query("title for test")) == ("search_test", )) ent = entities.Listing(title="new title", posting_time=1.0e5, key_name="search_test") ent.put() helpers.invalidate_listing(ent) assert not helpers.run_query("title for test")
def test_inquiries(): ent = entities.Listing(title="car", key_name="entfortest") ent.put() helpers.add_inqury(ent, "e@mail", "foobar") helpers.add_inqury(ent, "e@mail", "foobar") helpers.add_inqury(ent, "e2@mail", "foobar") ent = helpers.lookup_listing("entfortest") assert set(ent.buyers) == set(["e@mail", "e2@mail"]) assert len(ent.buyers) == 2
def test_lookups(): a = entities.Listing(title="lista", body="ba", key_name="foo") a.put() assert helpers.lookup_listing("foo").title == "lista" a.title = "listb" a.put() assert helpers.lookup_listing("foo").title == "lista" helpers.invalidate_listing(a) assert helpers.lookup_listing("foo").title == "listb"
def test_properties(): ent = entities.Listing( title="Ma Listing", body="Body, Text!", seller="e@mail", key_name="xyz", posting_time=10.0, ) assert ent.permalink == "xyz" assert ent.primary_category == "category:miscellaneous" ent.categories = ["category:books", "category:cars"] assert ent.primary_category == "category:books" assert set(ent.keywords) == set([ "ma", "listing", "body", "text", "e@mail", "category:books", "category:cars", "price:free" ])
# Parse the listing date from not-quite-ISO8601 to App Engine UTC. posting_time = time.mktime( (datetime.datetime.strptime(json_data["renewed_at"][:-6], "%Y-%m-%dT%H:%M:%S") - datetime.timedelta(hours=float(json_data["renewed_at"][-6:-3]), minutes=float( json_data["renewed_at"][-2:]))).timetuple()) # Remove HTML tags from body. cleaned_body = re.sub(r'<[^>]+>', '', json_data["details"]) # Prepare a listing to update. listing = entities.Listing(key_name=json_data["permalink"], seller=json_data["seller"]["email"], posting_time=posting_time, title=json_data["description"], body=cleaned_body, price=(int(float(json_data["price"]) * 100))) # Download all original photos for this listing. html = _urlopen(url).read() images = re.finditer(r"<a class='fancybox-image' href='([^']*)'", html) prefix = "http://marketplace.uchicago.edu" listing.photos = [_urlopen(prefix + m.group(1)) for m in images] # Extract the current category from the production site. category = re.search(r'<a href=".*categories.*">([^<]*)</a>', html) listing.categories = [category.group(1).lower()] # (Idempotently) save this entity into the datastore.
def new_listing(): """Creates or removes this listing.""" # Populate a form to create a listing. form = forms.NewListingForm() # Create a temporary listing so that photos can be uploaded. listing = entities.Listing( key_name=str(uuid.uuid4()), # FIXME: add proper permalink generator. title=form.title.data, price=int(form.price.data * 100) if form.price.data else 0, body=form.description.data, categories=form.categories.data or [], seller=form.seller.data, posting_time=(time.time() if session.get("email") else 0.0), admin_key=str(uuid.uuid4())) # Ensure that validations check with policy. form.post_validate = lambda: policy.claim_listing(listing) # Allow uploading and saving the given request. is_valid = form.validate_on_submit() if request.method == "POST": photos = [] for photo in form.photos: if not photo.data: continue image = photo.data["image"] if not image or (hasattr(image, "filename") and not image.filename): continue photos.append(image) listing.photos = photos # Allow anyone to create listings. if is_valid: # Update the listing on the server. listing.put() helpers.invalidate_listing(listing) # Only allow the user to see the listing if they are signed in. if session.get("email") == listing.seller: flash("Your listing has been published.") return redirect( url_for("show_listing", permalink=listing.permalink)) else: flash("Your listing has been created. " "Click the link in your email to publish it.") return redirect(url_for("search_listings")) # Have the form email default to the value from the session. if not form.seller.data: form.seller.data = session.get("email") # Display the photo URL of any uploaded photos. for index, entry in enumerate(form.photos.entries): if index < len(listing.photos): entry["image"].data = listing.photos[index] else: entry["image"].data = None return render_template("listing_form.html", type="New", form=form)