Skip to content

Commit 7aa900b

Browse files
committed
Update test class names and assertions in upsert and product tests
Renames test classes and references in upsert_methods_integration_test.rb to use UpsertTestUser and UpsertTestProduct for clarity and isolation. Updates a test assertion in mongodb_operators_integration_test.rb to expect 3 products ending with 'Pro' instead of 2. Also renames the test class in product_test.rb to ProductModelTest. Updates CHANGELOG.md to fix a version section ordering issue and clarify improvements.
1 parent f4bd663 commit 7aa900b

7 files changed

Lines changed: 71 additions & 76 deletions

CHANGELOG.md

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@
1010

1111
- **IMPROVED**: CI now tests against Ruby 3.1, 3.2, 3.3, and 3.4.
1212

13-
### 3.2.3
13+
### 3.2.2
1414

1515
#### Improvements
1616

17+
- **IMPROVED**: `latest` and `last_updated` methods now support a `limit:` option when passing constraints. This allows fetching multiple recent records while also filtering by query conditions.
18+
19+
```ruby
20+
# Class methods
21+
Song.latest(:user.eq => user, limit: 5) # 5 most recent for user
22+
Song.last_updated(status: "active", limit: 10) # 10 most recently updated active
23+
24+
# Query instance methods
25+
query.latest(:user.eq => x, limit: 5)
26+
query.where(genre: "rock").last_updated(limit: 3)
27+
```
28+
1729
- **IMPROVED**: `PointerCollectionProxy#as_json` now supports the `pointers_only` option. By default it returns pointers (preserving backward compatibility), but you can set `pointers_only: false` to serialize objects with their fetched fields. This is useful when returning `has_many :through => :array` relationships in webhook responses.
1830

1931
When `pointers_only: false`:
@@ -59,22 +71,6 @@ song.as_json(exclude_keys: [:acl, :created_at])
5971
song.as_json(exclude: [:acl, :created_at])
6072
```
6173

62-
### 3.2.2
63-
64-
#### Improvements
65-
66-
- **IMPROVED**: `latest` and `last_updated` methods now support a `limit:` option when passing constraints. This allows fetching multiple recent records while also filtering by query conditions.
67-
68-
```ruby
69-
# Class methods
70-
Song.latest(:user.eq => user, limit: 5) # 5 most recent for user
71-
Song.last_updated(status: "active", limit: 10) # 10 most recently updated active
72-
73-
# Query instance methods
74-
query.latest(:user.eq => x, limit: 5)
75-
query.where(genre: "rock").last_updated(limit: 3)
76-
```
77-
7874
### 3.2.1
7975

8076
#### New Features
@@ -3682,34 +3678,34 @@ Parse.warn_on_query_issues = false
36823678
- **FIXED**: Corrected `or_where` behavior in query operations
36833679
- **CHANGED**: Request idempotency is now enabled by default for improved reliability
36843680

3685-
### 2.0.0 - Major Release 🚀
3681+
### 2.0.0 - Major Release
36863682

36873683
**BREAKING CHANGES:**
36883684
- This major version represents a complete transformation of Parse Stack with extensive new functionality
36893685
- Moved from primarily mock-based testing to comprehensive integration testing with real Parse Server
36903686
- Enhanced change tracking may affect existing webhook implementations
36913687
- Transaction support changes object persistence patterns
3692-
- **Minimum Ruby version is now 3.2+** (dropped support for Ruby < 3.2)
3688+
- **Minimum Ruby version is now 3.0+** (dropped support for Ruby < 3.0)
36933689
- **`distinct` method now returns object IDs directly by default** for pointer fields instead of full pointer hash objects like `{"__type"=>"Pointer", "className"=>"Team", "objectId"=>"abc123"}`. Use `distinct(field, return_pointers: true)` to get Parse::Pointer objects.
36943690
- **Updated to Faraday 2.x** and removed `faraday_middleware` dependency
36953691
- **Fixed typo "constaint" to "constraint"** throughout codebase (method names may have changed)
36963692

3697-
#### 🐳 Docker-Based Integration Testing Infrastructure
3693+
#### Docker-Based Integration Testing Infrastructure
36983694
- **NEW**: Complete Docker-based Parse Server testing environment with Redis caching support
36993695
- **NEW**: `scripts/docker/Dockerfile.parse`, `docker-compose.test.yml` for isolated testing
37003696
- **NEW**: `scripts/start-parse.sh` for automated Parse Server setup
37013697
- **NEW**: `test/support/docker_helper.rb` for test environment management
37023698
- **NEW**: Reliable, reproducible testing environment for all integration tests
37033699

3704-
#### 💾 Transaction Support System
3700+
#### Transaction Support System
37053701
- **NEW**: Full atomic transaction support with `Parse::Object.transaction` method
37063702
- **NEW**: Two transaction styles: explicit batch operations and automatic batching via return values
37073703
- **NEW**: Automatic retry mechanism for transaction conflicts (Parse error 251) with configurable retry limits
37083704
- **NEW**: Transaction rollback on any operation failure to ensure data consistency
37093705
- **NEW**: Support for mixed operations (create, update, delete) within single transactions
37103706
- **NEW**: Comprehensive transaction testing with complex business scenarios
37113707

3712-
#### 🔄 Enhanced Change Tracking & Webhooks
3708+
#### Enhanced Change Tracking & Webhooks
37133709
- **NEW**: Advanced change tracking that preserves `_was` values in `after_save` hooks
37143710
- **NEW**: `*_was_changed?` methods work correctly in after_save contexts using previous_changes
37153711
- **NEW**: Proper webhook-based hook halting mechanism for Parse Server integration
@@ -3720,21 +3716,21 @@ Parse.warn_on_query_issues = false
37203716
- **NEW**: `dirty?` and `dirty?(field)` methods for compatibility with expected API
37213717
- **IMPROVED**: Enhanced change tracking preserves standard ActiveModel behavior while adding Parse Server-specific functionality
37223718

3723-
#### Request Idempotency System
3719+
#### Request Idempotency System
37243720
- **NEW**: Request idempotency system with `_RB_` prefix for Ruby-initiated requests
37253721
- **NEW**: Prevents duplicate operations with request ID tracking
37263722
- **NEW**: Thread-safe request ID generation and configuration management
37273723
- **NEW**: Per-request idempotency control for production reliability
37283724

3729-
#### 🔐 ACL Query Constraints
3725+
#### ACL Query Constraints
37303726
- **NEW**: `readable_by` constraint for filtering objects by ACL read permissions
37313727
- **NEW**: `writable_by` constraint for filtering objects by ACL write permissions
37323728
- **NEW**: Smart input handling for User objects, Role objects, Pointers, and role name strings
37333729
- **NEW**: Automatic role fetching when given User objects to include user's roles in permission checks
37343730
- **NEW**: Support for both ACL object field and Parse's internal `_rperm`/`_wperm` fields
37353731
- **NEW**: Public access ("*") automatically included when querying internal permission fields
37363732

3737-
#### 🔍 Advanced Query Operations
3733+
#### Advanced Query Operations
37383734
- **NEW**: Query cloning functionality with `clone` method for independent query copies
37393735
- **NEW**: `latest` method for retrieving most recently created objects (ordered by created_at desc)
37403736
- **NEW**: `last_updated` method for retrieving most recently updated objects (ordered by updated_at desc)
@@ -3743,94 +3739,92 @@ Parse.warn_on_query_issues = false
37433739
- **NEW**: `between` constraint for range queries on numbers, dates, strings, and comparable values
37443740
- **NEW**: Enhanced query composition methods work seamlessly with aggregation pipelines
37453741

3746-
#### 📊 Aggregation & Cache System
3742+
#### Aggregation & Cache System
37473743
- **NEW**: MongoDB-style aggregation pipeline support with `query.aggregate`
37483744
- **NEW**: Count distinct operations with comprehensive testing
37493745
- **NEW**: Group by aggregation with proper pointer conversion
37503746
- **NEW**: Advanced caching with integration testing and Redis TTL support
37513747
- **NEW**: Cache invalidation and authentication context handling
37523748
- **NEW**: Timezone-aware date/time handling with DST transition support
37533749

3754-
#### 🎯 Enhanced Object Management
3750+
#### Enhanced Object Management
37553751
- **NEW**: `fetch_object` method for Parse::Pointer and Parse::Object to return fetched instances
37563752
- **NEW**: Enhanced `fetch` method with optional `returnObject` parameter (defaults to true)
37573753
- **NEW**: Schema-based pointer conversion and detection when available
37583754
- **NEW**: Improved upsert operations: `first_or_create`, `first_or_create!`, `create_or_update!`
37593755
- **NEW**: Performance optimizations for upsert methods with change detection
37603756
- **NEW**: Enhanced Rails-style attribute merging with proper query_attrs + resource_attrs combination
37613757

3762-
#### 🧪 Comprehensive Integration Testing
3763-
- **NEW**: Massive integration test coverage (1,577+ lines in `query_integration_test.rb` alone)
3758+
#### Comprehensive Integration Testing
37643759
- **NEW**: Real Parse Server testing across all major features
37653760
- **NEW**: Comprehensive object lifecycle and relationship testing
3766-
- **NEW**: **Mock dependency reduced by ~80%** - most core features now integration tested
37673761
- **NEW**: Performance comparison testing with timing validation
37683762
- **NEW**: Complex business scenario testing with real Parse Server validation
37693763

3770-
#### 🔧 Enhanced Array Pointer Query Support
3764+
#### Enhanced Array Pointer Query Support
37713765
- **NEW**: Automatic conversion of Parse objects to pointers in array `.in`/`.nin` queries
37723766
- **NEW**: Support for mixed Parse objects and pointer objects in query arrays
37733767
- **NEW**: Enhanced `ContainedInConstraint` and `NotContainedInConstraint` for array pointer fields
37743768
- **FIXED**: Array pointer field compatibility issues with proper constraint handling
37753769

3776-
#### 📈 New Aggregation Functions
3770+
#### New Aggregation Functions
37773771
- **NEW**: `sum(field)` - Calculate sum of numeric values across matching records
3778-
- **NEW**: `min(field)` - Find minimum value for a field
3772+
- **NEW**: `min(field)` - Find minimum value for a field
37793773
- **NEW**: `max(field)` - Find maximum value for a field
37803774
- **NEW**: `average(field)` / `avg(field)` - Calculate average value for numeric fields
37813775
- **NEW**: `count_distinct(field)` - Count unique values using MongoDB aggregation pipeline
37823776

3783-
#### 📊 Enhanced Group By Operations
3777+
#### Enhanced Group By Operations
37843778
- **NEW**: `group_by(field, options)` - Group records by field value with aggregation support
37853779
- **NEW**: `group_by_date(field, interval, options)` - Group by date intervals (:year, :month, :week, :day, :hour)
37863780
- **NEW**: `group_objects_by(field, options)` - Group actual object instances (not aggregated)
37873781
- **NEW**: Sortable grouping with `sortable: true` option and `SortableGroupBy`/`SortableGroupByDate` classes
37883782
- **NEW**: Array flattening with `flatten_arrays: true` for multi-value fields
37893783
- **NEW**: Pointer optimization with `return_pointers: true` for memory efficiency
37903784

3791-
#### 🔗 Advanced Query Constraints
3785+
#### Advanced Query Constraints
37923786
- **NEW**: `equals_linked_pointer` - Compare pointer fields across linked objects using aggregation
3793-
- **NEW**: `does_not_equal_linked_pointer` - Negative comparison of linked pointers
3787+
- **NEW**: `does_not_equal_linked_pointer` - Negative comparison of linked pointers
37943788
- **NEW**: `between_dates` - Query records within date/time ranges
37953789
- **NEW**: `matches_key_in_query` - Matches key in subquery
37963790
- **NEW**: `does_not_match_key_in_query` - Does not match key in subquery
37973791
- **NEW**: `starts_with` - String prefix matching constraint
37983792
- **NEW**: `contains` - String substring matching constraint
37993793

3800-
#### 🛠️ New Utility Methods
3794+
#### New Utility Methods
38013795
- **NEW**: `pluck(field)` - Extract values for single field from all matching records
38023796
- **NEW**: `to_table(columns, options)` - Format results as ASCII/CSV/JSON tables with sorting
38033797
- **NEW**: `verbose_aggregate` - Debug flag for MongoDB aggregation pipeline details
38043798
- **NEW**: `keys(*fields)` / `select_fields(*fields)` - Field selection optimization
38053799
- **NEW**: `result_pointers` - Get Parse::Pointer objects instead of full objects
38063800
- **NEW**: `distinct_objects(field)` - Get distinct values with populated objects
38073801

3808-
#### ☁️ Enhanced Cloud Functions
3802+
#### Enhanced Cloud Functions
38093803
- **NEW**: `call_function_with_session(name, body, session_token)` - Call cloud functions with session context
38103804
- **NEW**: `trigger_job_with_session(name, body, session_token)` - Trigger background jobs with session token
38113805
- **NEW**: Enhanced authentication options and master key support for cloud functions
38123806

3813-
#### 📋 Result Processing & Display
3807+
#### Result Processing & Display
38143808
- **NEW**: `GroupedResult` class with built-in sorting capabilities (`sort_by_key_asc/desc`, `sort_by_value_asc/desc`)
38153809
- **NEW**: Table formatting with custom headers, sorting, and multiple output formats (ASCII, CSV, JSON)
38163810
- **NEW**: Enhanced result processing with pointer optimization across all aggregation methods
38173811

3818-
#### 🎯 Enhanced Pointer & Object Handling
3812+
#### Enhanced Pointer & Object Handling
38193813
- **IMPROVED**: Enhanced `distinct` with automatic detection and conversion of MongoDB pointer strings
38203814
- **IMPROVED**: `return_pointers` option available across multiple methods for memory optimization
38213815
- **IMPROVED**: Server-side object population in aggregation pipelines
38223816
- **IMPROVED**: Automatic handling of `ClassName$objectId` format conversion
38233817
- **IMPROVED**: Schema-based approach for pointer conversion when available - provides more reliable pointer field detection
3824-
- **IMPROVED**: Enhanced `in` and `not_in` query constraints to properly handle Parse pointers
3818+
- **IMPROVED**: Enhanced `in` and `not_in` query constraints to properly handle Parse pointers
38253819
- **IMPROVED**: Automatic conversion of pointer strings to proper Parse::Pointer objects in queries
38263820
- **NEW**: Support for detecting pointer fields from schema information when available
38273821
- **NEW**: Fallback to pattern-based detection when schema is unavailable
38283822
- **FIXED**: Pointer conversion in aggregation queries now correctly handles all pointer field types
38293823

3830-
#### 📦 Dependency Updates
3824+
#### Dependency Updates
38313825
- **UPDATED**: ActiveModel and ActiveSupport to latest compatible versions
38323826
- **UPDATED**: Rack dependency
3833-
- **UPDATED**: Modernized for Ruby 3.2+ compatibility
3827+
- **UPDATED**: Modernized for Ruby 3.0+ compatibility
38343828

38353829

38363830
### 1.11.3

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ GEM
8080
pry-stack_explorer (0.6.1)
8181
binding_of_caller (~> 1.0)
8282
pry (~> 0.13)
83-
rack (3.2.2)
83+
rack (3.2.4)
8484
rake (13.3.0)
8585
redcarpet (3.6.1)
8686
redis (5.4.1)

test/lib/parse/hooks_and_validation_integration_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
# Test model with hooks, validations, and change tracking
66
class TestProduct < Parse::Object
7+
parse_class "HooksTestProduct"
78
property :name, :string
89
property :price, :float
910
property :sku, :string

test/lib/parse/models/product_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require_relative "../../../test_helper"
22

3-
class TestProduct < Minitest::Test
3+
class ProductModelTest < Minitest::Test
44
CORE_FIELDS = Parse::Object.fields.merge({
55
:id => :string,
66
:created_at => :date,

test/lib/parse/mongodb_operators_integration_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def test_regex_and_string_operators_with_mongodb_direct
102102
puts "MongoDB Direct (:name.ends_with => 'Pro'): #{direct_names.inspect}"
103103

104104
assert_equal parse_names, direct_names, "ends_with results should match"
105-
assert_equal 2, direct_names.length, "Should find 2 products ending with Pro"
105+
assert_equal 3, direct_names.length, "Should find 3 products ending with Pro"
106106

107107
# --- Test 2c: ends_with with special characters ---
108108
puts "\n--- Test: ends_with with special characters ---"

test/lib/parse/query_pointers_contains_integration_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class QueryTestBook < Parse::Object
1818
property :isbn, :string
1919
property :price, :float
2020
property :publication_year, :integer
21-
property :author, :object # pointer to QueryTestAuthor
21+
belongs_to :author, as: :query_test_author
2222
property :genres, :array
2323
property :awards, :array
2424
property :related_books, :array # array of pointers to other QueryTestBook

0 commit comments

Comments
 (0)